ddc-core-eval 0.3.2.1 → 0.4.1.1
raw patch · 10 files changed
+149/−162 lines, 10 filesdep ~arraydep ~basedep ~ddc-base
Dependency ranges changed: array, base, ddc-base, ddc-core
Files
- DDC/Core/Eval/Check.hs +14/−14
- DDC/Core/Eval/Compounds.hs +13/−26
- DDC/Core/Eval/Env.hs +17/−13
- DDC/Core/Eval/Name.hs +41/−31
- DDC/Core/Eval/Prim.hs +16/−16
- DDC/Core/Eval/Profile.hs +3/−3
- DDC/Core/Eval/Step.hs +15/−16
- DDC/Core/Eval/Store.hs +23/−23
- LICENSE +1/−15
- ddc-core-eval.cabal +6/−5
DDC/Core/Eval/Check.hs view
@@ -14,14 +14,14 @@ import Control.Monad import Data.Maybe import Data.Set (Set)-import DDC.Control.Monad.Check (throw, result)+import DDC.Control.Monad.Check (evalCheck, throw) import qualified DDC.Control.Monad.Check as G import qualified Data.Set as Set -- | Capability Checking monad. type CheckM a x - = G.CheckM (Error a) x+ = G.CheckM () (Error a) x -- | Check for conflicting store capabilities in a module.@@ -33,7 +33,7 @@ -- | Check for conflicting store capabilities in an expression. checkCapsX :: Exp a Name -> Maybe (Error a) checkCapsX xx - = case result $ checkCapsXM xx of+ = case evalCheck () $ checkCapsXM xx of Left err -> Just err Right ws -> let caps = foldr mustInsertCap emptyCapSet ws@@ -68,8 +68,8 @@ -- | Insert a capability, or `error` if this isn't one. mustInsertCap :: Witness a Name -> CapSet -> CapSet mustInsertCap ww caps- | WApp _ (WCon _ (WiConBound (UPrim nc _) _)) - (WType _ (TCon (TyConBound (UPrim nh _) _))) <- ww+ | WApp _ (WCon _ (WiConBound (UPrim nc _) _))+ (WType _ (TVar (UPrim nh _))) <- ww , NameCap c <- nc , NameRgn r <- nh = case c of@@ -86,13 +86,13 @@ = caps { capsDistinct = Set.insert (catMaybes ws') (capsDistinct caps) } | otherwise- = error "mustInsertCap: not a capability"+ = error "ddc-core-eval.mustInsertCap: not a capability" -- | Take a region name from a witness argument. takeNameRgn :: Witness a Name -> Maybe Rgn-takeNameRgn (WType _ (TCon (TyConBound (UPrim (NameRgn r) _) _))) = Just r-takeNameRgn _ = Nothing+takeNameRgn (WType _ (TVar (UPrim (NameRgn r) _))) = Just r+takeNameRgn _ = Nothing -- | Check a capability set for conflicts between the capabilities.@@ -170,7 +170,7 @@ (liftM concat $ mapM checkCapsAM alts) XCast _ cc x1 -> liftM2 (++) (checkCapsCM cc) (checkCapsXM x1) XType{} -> none- XWitness w -> checkCapsWM w+ XWitness _ w -> checkCapsWM w checkCapsCM :: Cast a Name -> CheckM a [Witness a Name]@@ -183,10 +183,10 @@ CastWeakenClosure xs -> liftM concat $ mapM checkCapsXM xs - CastPurify w -> checkCapsWM w- CastForget w -> checkCapsWM w- CastSuspend -> none - CastRun -> none+ CastPurify w -> checkCapsWM w+ CastForget w -> checkCapsWM w+ CastBox -> none + CastRun -> none checkCapsLM :: Lets a Name -> CheckM a [Witness a Name]@@ -195,7 +195,7 @@ in case ll of LLet _ x -> checkCapsXM x LRec bxs -> liftM concat (mapM checkCapsXM $ map snd bxs)- LLetRegions{} -> none+ LPrivate{} -> none LWithRegion{} -> none
DDC/Core/Eval/Compounds.hs view
@@ -120,7 +120,7 @@ isUnitX xx = case xx of XCon _ dc- -> case daConName dc of+ -> case dc of DaConUnit -> True _ -> False _ -> False@@ -131,7 +131,7 @@ takeHandleT :: Type Name -> Maybe Rgn takeHandleT tt = case tt of- TCon (TyConBound (UPrim (NameRgn r1) _) _)+ TVar (UPrim (NameRgn r1) _) -> Just r1 _ -> Nothing @@ -140,15 +140,15 @@ takeHandleX :: Exp a Name -> Maybe Rgn takeHandleX xx = case xx of- XType t -> takeHandleT t- _ -> Nothing+ XType _ t -> takeHandleT t+ _ -> Nothing -- Locations ------------------------------------ -- | Make a location expression. xLoc :: Loc -> Type Name -> Exp () Name xLoc l t- = XCon () $ mkDaConSolid (NameLoc l) t+ = XVar () (UPrim (NameLoc l) t) -- | Take a store location from an expression.@@ -156,31 +156,18 @@ takeLocX :: Exp a Name -> Maybe Loc takeLocX xx = case xx of- XCast _ (CastForget _) x- -> takeLocX x-- XCon _ dc- -> case takeNameOfDaCon dc of- Just (NameLoc l) -> Just l- _ -> Nothing-- _ -> Nothing+ XCast _ (CastForget _) x -> takeLocX x+ XVar _ (UPrim (NameLoc l) _) -> Just l+ _ -> Nothing -- | Take a store location from an expression, reaching under any 'forget' casts. stripLocX :: Exp a Name -> Maybe Loc stripLocX xx = case xx of- XCast _ (CastForget _) x- -> stripLocX x--- XCon _ dc- -> case takeNameOfDaCon dc of- Just (NameLoc l) -> Just l- _ -> Nothing-- _ -> Nothing+ XCast _ (CastForget _) x -> stripLocX x+ XVar _ (UPrim (NameLoc l) _) -> Just l+ _ -> Nothing -- Witnesses ------------------------------------@@ -188,7 +175,7 @@ takeMutableX :: Exp a Name -> Maybe Rgn takeMutableX xx = case xx of- XWitness (WApp _ (WCon _ wc) (WType _ tR1))+ XWitness _ (WApp _ (WCon _ wc) (WType _ tR1)) | WiConBound (UPrim (NameCap CapMutable) _) _ <- wc -> takeHandleT tR1 _ -> Nothing@@ -209,7 +196,7 @@ -- | Make an integer data constructor. dcInt :: Integer -> DaCon Name-dcInt i = mkDaConAlg (NameInt i) (TCon tcInt)+dcInt i = DaConPrim (NameInt i) (TCon tcInt) -- | Take an integer literal from an data constructor.
DDC/Core/Eval/Env.hs view
@@ -38,24 +38,25 @@ primDataDefs = fromListDataDefs [ -- Int- DataDef+ makeDataDefAlg (NamePrimCon PrimTyConInt)- [kRegion]+ [BAnon kRegion] Nothing -- Pair- , DataDef+ , makeDataDefAlg (NamePrimCon PrimTyConPair)- [kRegion, kData, kData]+ [BAnon kRegion, BAnon kData, BAnon kData] (Just [ ( NamePrimCon PrimDaConPr , [tIx kData 1, tIx kData 0]) ]) -- List- , DataDef+ , makeDataDefAlg (NamePrimCon PrimTyConList)- [kRegion, kData]+ [BAnon kRegion, BAnon kData] (Just [ (NamePrimCon PrimDaConNil, []) - , (NamePrimCon PrimDaConCons, [tList (tIx kRegion 1) (tIx kData 0)])])+ , (NamePrimCon PrimDaConCons, + [tList (tIx kRegion 1) (tIx kData 0)])]) ] @@ -177,12 +178,15 @@ (tBot kClosure) $ (tInt r0) - NameCap CapGlobal -> Just $ tForall kRegion $ \r -> tGlobal r- NameCap CapConst -> Just $ tForall kRegion $ \r -> tConst r- NameCap CapMutable -> Just $ tForall kRegion $ \r -> tMutable r- NameCap CapLazy -> Just $ tForall kRegion $ \r -> tLazy r- NameCap CapManifest -> Just $ tForall kRegion $ \r -> tManifest r- NameCap (CapDistinct n) -> Just $ tForalls (replicate n kRegion) $ \rs -> tDistinct n rs+ NameCap CapGlobal -> Just $ tForall kRegion $ \r -> tGlobal r+ NameCap CapConst -> Just $ tForall kRegion $ \r -> tConst r+ NameCap CapMutable -> Just $ tForall kRegion $ \r -> tMutable r+ NameCap CapLazy -> Just $ tForall kRegion $ \r -> tLazy r+ NameCap CapManifest -> Just $ tForall kRegion $ \r -> tManifest r+ NameCap (CapDistinct n) -> Just $ tForalls (replicate n kRegion) + $ \rs -> tDistinct n rs++ NameLoc (Loc _ t) -> Just t _ -> Nothing
DDC/Core/Eval/Name.hs view
@@ -13,6 +13,8 @@ import DDC.Core.Lexer import DDC.Base.Pretty import DDC.Data.Token+import DDC.Type.Exp+import DDC.Type.Compounds import Control.DeepSeq import Data.Typeable import Data.Char@@ -41,14 +43,14 @@ instance NFData Name where rnf nn = case nn of- NameVar s -> rnf s- NameCon s -> rnf s- NameInt i -> rnf i- NamePrimCon pc -> rnf pc- NamePrimOp po -> rnf po- NameLoc l -> rnf l- NameRgn r -> rnf r- NameCap c -> rnf c+ NameVar s -> rnf s+ NameCon s -> rnf s+ NameInt i -> rnf i+ NamePrimCon pc -> rnf pc+ NamePrimOp po -> rnf po+ NameLoc l -> rnf l+ NameRgn r -> rnf r+ NameCap c -> rnf c instance Pretty Name where@@ -65,26 +67,34 @@ -- Locations --------------------------------------------------------------------- | A store location.+-- | A store location,+-- tagged with the type of the value contained at that location. ----- These are pretty printed like @L4#@.+-- These are pretty printed like @l4#@. data Loc- = Loc Int- deriving (Eq, Ord, Show)+ = Loc Int (Type Name)+ deriving Show instance NFData Loc where- rnf (Loc i) = rnf i-+ rnf (Loc i t) = rnf i `seq` rnf t instance Pretty Loc where- ppr (Loc l) = text "L" <> text (show l) <> text "#"- + ppr (Loc l _) = text "l" <> text (show l) <> text "#" +instance Eq Loc where+ (==) (Loc l1 _) (Loc l2 _) + = l1 == l2++instance Ord Loc where+ compare (Loc l1 _) (Loc l2 _)+ = compare l1 l2++ -- Regions -------------------------------------------------------------------- -- | A region handle. ----- These are pretty printed like @R5#@.+-- These are pretty printed like @r5#@. data Rgn = Rgn Int deriving (Eq, Ord, Show)@@ -93,7 +103,7 @@ rnf (Rgn i) = rnf i instance Pretty Rgn where- ppr (Rgn r) = text "R" <> text (show r) <> text "#"+ ppr (Rgn r) = text "r" <> text (show r) <> text "#" -- Capabilities --------------------------------------------------------------@@ -214,6 +224,18 @@ readName :: String -> Maybe Name readName [] = Nothing readName str@(c:rest)+ -- region handles+ | c == 'r'+ , (ds, "#") <- span isDigit rest+ , not $ null ds+ = Just $ NameRgn (Rgn $ read ds)+ + -- store locations+ | c == 'l'+ , (ds, "#") <- span isDigit rest+ , not $ null ds+ = Just $ NameLoc (Loc (read ds) (tBot kData))+ -- primops and variables. | isLower c = case (c:rest) of@@ -245,19 +267,7 @@ | str == "List" = Just $ NamePrimCon PrimTyConList | str == "Nil" = Just $ NamePrimCon PrimDaConNil | str == "Cons" = Just $ NamePrimCon PrimDaConCons- - -- region handles- | c == 'R'- , (ds, "#") <- span isDigit rest- , not $ null ds- = Just $ NameRgn (Rgn $ read ds)- - -- store locations- | c == 'L'- , (ds, "#") <- span isDigit rest- , not $ null ds- = Just $ NameLoc (Loc $ read ds)- + -- store capabilities | str == "Global#" = Just $ NameCap CapGlobal | str == "Const#" = Just $ NameCap CapConst
DDC/Core/Eval/Prim.hs view
@@ -15,6 +15,7 @@ import DDC.Core.Exp import qualified DDC.Core.Eval.Store as Store + ------------------------------------------------------------------------------- -- | Step a primitive constructor, which allocates an object in the store. stepPrimCon@@ -25,11 +26,10 @@ , Exp () Name) -- ^ New store and result expression, -- if the operator steps, otherwise `Nothing`. - -- Redirect the unit constructor. -- All unit values point to the same object in the store. stepPrimCon dc xsArgs store- | DaConUnit <- daConName dc+ | DaConUnit <- dc , [] <- xsArgs = Just ( store , xLoc locUnit tUnit )@@ -42,7 +42,7 @@ , [xR, xUnit'] <- xsArgs -- unpack the args- , XType tR <- xR+ , XType _ tR <- xR , Just rgn <- takeHandleT tR , isUnitOrLocX xUnit' @@ -62,12 +62,12 @@ , [xR, xA, xB, x1, x2] <- xsArgs -- unpack the args- , XType tR <- xR- , Just rgn <- takeHandleT tR- , XType tA <- xA- , XType tB <- xB- , Just l1 <- takeLocX x1- , Just l2 <- takeLocX x2+ , XType _ tR <- xR+ , Just rgn <- takeHandleT tR+ , XType _ tA <- xA+ , XType _ tB <- xB+ , Just l1 <- takeLocX x1+ , Just l2 <- takeLocX x2 -- the store must contain the region we're going to allocate into. , Store.hasRgn store rgn@@ -85,9 +85,9 @@ , [xR, xA, xUnit'] <- xsArgs -- unpack the args- , XType tR <- xR- , Just rgn <- takeHandleT tR- , XType tA <- xA+ , XType _ tR <- xR+ , Just rgn <- takeHandleT tR+ , XType _ tA <- xA , isUnitOrLocX xUnit' -- the store must contain the region we're going to allocate into.@@ -104,9 +104,9 @@ , [xR, xA, xHead, xTail] <- xsArgs -- unpack the args- , XType tR <- xR+ , XType _ tR <- xR , Just rgn <- takeHandleT tR- , XType tA <- xA+ , XType _ tA <- xA , Just lHead <- takeLocX xHead , Just lTail <- takeLocX xTail @@ -145,7 +145,7 @@ , (PrimOpEqInt, (\x y -> if x == y then 1 else 0))] , Just r1 <- takeHandleX xR1 , Just r2 <- takeHandleX xR2- , XType tR3 <- xR3+ , XType _ tR3 <- xR3 , Just r3 <- takeHandleX xR3 , Just l1 <- stripLocX xL1 , Just l2 <- stripLocX xL2@@ -211,7 +211,7 @@ [ (PrimOpCopyInt, id) , (PrimOpNegInt, negate) ] , Just r1 <- takeHandleX xR1- , XType tR2 <- xR2+ , XType _ tR2 <- xR2 , Just r2 <- takeHandleX xR2 , Just l1 <- stripLocX xL1
DDC/Core/Eval/Profile.hs view
@@ -6,7 +6,6 @@ import DDC.Core.Fragment import DDC.Core.Eval.Env import DDC.Core.Eval.Name-import qualified DDC.Type.Env as Env -- | Core language fragment that can be directly evaluated.@@ -16,10 +15,10 @@ { profileName = "Eval" , profileFeatures = evalFeatures , profilePrimDataDefs = primDataDefs- , profilePrimSupers = Env.empty , profilePrimKinds = primKindEnv , profilePrimTypes = primTypeEnv - , profileTypeIsUnboxed = const False }+ , profileTypeIsUnboxed = const False + , profileNameIsHole = Nothing } -- | Language features used by the eval fragment.@@ -30,6 +29,7 @@ , featuresTrackedClosures = True , featuresFunctionalEffects = True , featuresFunctionalClosures = True+ , featuresEffectCapabilities = False , featuresPartialPrims = False , featuresPartialApplication = True , featuresGeneralApplication = True
DDC/Core/Eval/Step.hs view
@@ -56,8 +56,7 @@ force store xx | (casts, xx') <- unwrapCasts xx- , XCon _ dc <- xx'- , Just (NameLoc l) <- takeNameOfDaCon dc+ , XVar _ (UPrim (NameLoc l) _) <- xx' , Just (rgn, t, SThunk x) <- lookupRegionTypeBind l store = case force store x of StepProgress store' x'@@ -117,7 +116,8 @@ -- Step a primitive operator or constructor defined by the client. step store xx | Just (x1@(XVar _ (UPrim p _)), xs) <- takeXApps xx- , Just arity <- arityOfName p+ , Nothing <- takeLocX x1+ , Just arity <- arityOfName p = let -- ISSUE #296: Evaluator doesn't support over-applied primops. -- This would be a problem if we read a reference to a function@@ -134,7 +134,8 @@ stepArg i acc (ax:axs) = case force store ax of StepProgress store' x' - -> Right (store', xApps () x1 (reverse acc ++ (x' : axs)))+ -> Right ( store'+ , xApps () x1 (reverse acc ++ (x' : axs))) StepDone -> case stepArg (i + 1) (ax : acc) axs of@@ -164,7 +165,7 @@ -- This should never error, as we took as many args -- as we had wnf flags. stepArg _ [] - = error "stepArg: no more args"+ = error "ddc-core-eval.stepArg: no more args" stepArg [] xs = Right (store, xs)@@ -254,7 +255,7 @@ ts = map typeOfBind bs -- Allocate new locations in the store to hold the expressions.- (store1, ls) = newLocs (length bs) store+ (store1, ls) = newLocs (map (typeOfBind . fst) bxs) store xls = [xLoc l t | (l, t) <- zip ls ts] -- Substitute locations into all the bindings.@@ -283,13 +284,13 @@ -- (EvCreateRegion) -- Create a new region.-step store (XLet a (LLetRegions bRegions bws) x)+step store (XLet a (LPrivate bRegions _mt bws) x) | uRegions <- takeSubstBoundsOfBinds bRegions -- Allocate a new region handle for the bound region. , (store1, uHandle@(UPrim (NameRgn rgn) _)) <- primNewRegion store- , tHandle <- TCon $ TyConBound uHandle kRegion+ , tHandle <- TVar uHandle -- Substitute handle into the witness types. , bws' <- concatMap @@ -477,12 +478,11 @@ isSomeValue :: Bool -> Store -> Exp a Name -> Bool isSomeValue weak store xx = case xx of- XVar{} -> True+ XVar _ (UPrim (NameLoc l) _)+ | Just SThunk{} <- lookupBind l store -> weak+ | otherwise -> True - XCon _ dc- | Just (NameLoc l) <- takeNameOfDaCon dc- , Just SThunk{} <- lookupBind l store- -> weak+ XVar{} -> True XCon{} -> True @@ -513,9 +513,8 @@ -> False -- Application of a lambda in the store is not wnf.- | Just (dc, _xs) <- takeXConApps xx- , Just (NameLoc l) <- takeNameOfDaCon dc- , Just SLams{} <- lookupBind l store+ | Just (NameLoc l, _xs) <- takeXPrimApps xx+ , Just SLams{} <- lookupBind l store -> False -- Application of a data constructor to enough args is not wnf.
DDC/Core/Eval/Store.hs view
@@ -87,10 +87,10 @@ , text " NextLoc: " <> text (show nextLoc) , text " NextRgn: " <> text (show nextRgn) - , text " Regions: " <> braces (sep $ punctuate comma + , text " Regions: " <> braces (sep $ punctuate comma $ map ppr $ Set.toList regions) - , text " Global: " <> braces (sep $ punctuate comma+ , text " Global: " <> braces (sep $ punctuate comma $ map ppr $ Set.toList global) , text "" , text " Binds:"@@ -132,43 +132,43 @@ , storeBinds = Map.fromList - [ (Loc 0, (Rgn 0, tUnit, SObj dcUnit []))]+ [ (Loc 0 tUnit, (Rgn 0, tUnit, SObj dcUnit []))] } -- | Location of the static unit object. locUnit :: Loc-locUnit = Loc 0+locUnit = Loc 0 tUnit -- | Check whether an expression is the unit constructor, -- or its static heap location.-isUnitOrLocX :: Exp a Name -> Bool-isUnitOrLocX (XCon _ dc)- = case daConName dc of- DaConUnit -> True- DaConNamed (NameLoc l) -> l == locUnit- _ -> False-isUnitOrLocX _ = False+isUnitOrLocX :: Show a => Exp a Name -> Bool+isUnitOrLocX xx+ = case xx of+ XCon _ DaConUnit -> True+ XVar _ (UPrim (NameLoc (Loc 0 _)) _) -> True+ _ -> False -- Locations ------------------------------------------------------------------ -- | Create a new location in the store.-newLoc :: Store -> (Store, Loc)-newLoc store+newLoc :: Type Name -> Store -> (Store, Loc)+newLoc t store = let loc = storeNextLoc store store' = store { storeNextLoc = loc + 1 }- in (store', Loc loc)+ in (store', Loc loc t) -- | Create several new locations in the store.-newLocs :: Int -> Store -> (Store, [Loc])-newLocs n store- = let lFirst = storeNextLoc store+newLocs :: [Type Name] -> Store -> (Store, [Loc])+newLocs ts store+ = let n = length ts+ lFirst = storeNextLoc store lLast = lFirst + n locs = [lFirst .. lLast] store' = store { storeNextLoc = lLast + 1 }- in (store', map Loc locs)+ in (store', [Loc l t | l <- locs | t <- ts]) -- Regions -------------------------------------------------------------------@@ -226,17 +226,16 @@ -- returning the new location. allocBind :: Rgn -> Type Name -> SBind -> Store -> (Store, Loc) allocBind rgn t sbind store- = let (store1, loc) = newLoc store+ = let (store1, loc) = newLoc t store store2 = addBind loc rgn t sbind store1 in (store2, loc) -- | Alloc some recursive bindings into the given region, -- returning the new locations.-allocBinds :: ([[Loc] -> (Rgn, Type Name, SBind)]) -> Store -> (Store, [Loc])-allocBinds mkSBinds store- = let n = length mkSBinds- (store1, locs) = newLocs n store+allocBinds :: [[Loc] -> (Rgn, Type Name, SBind)] -> [Type Name] -> Store -> (Store, [Loc])+allocBinds mkSBinds ts store+ = let (store1, locs) = newLocs ts store rgnBinds = map (\mk -> mk locs) mkSBinds store2 = foldr (\(l, (r, t, b)) -> addBind l r t b) store1 $ zip locs rgnBinds @@ -256,6 +255,7 @@ = case Map.lookup loc (storeBinds store) of Nothing -> Nothing Just (_, t, _) -> Just t+ -- | Lookup the region handle, type and binding for a location. lookupRegionTypeBind :: Loc -> Store -> Maybe (Rgn, Type Name, SBind)
LICENSE view
@@ -1,7 +1,7 @@ -------------------------------------------------------------------------------- The Disciplined Disciple Compiler License (MIT style) -Copyrite (K) 2007-2013 The Disciplined Disciple Compiler Strike Force+Copyrite (K) 2007-2014 The Disciplined Disciple Compiler Strike Force All rights reversed. Permission is hereby granted, free of charge, to any person obtaining a copy@@ -13,18 +13,4 @@ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.----------------------------------------------------------------------------------Under Australian law copyright is free and automatic.-By contributing to DDC authors grant all rights they have regarding their-contributions to the other members of the Disciplined Disciple Compiler Strike-Force, past, present and future, as well as placing their contributions under-the above license.--Use "darcs show authors" to get a list of Strike Force members.- ---------------------------------------------------------------------------------Redistributions of libraries in ./external are governed by their own licenses:-- - TinyPTC GNU Lesser General Public License-
ddc-core-eval.cabal view
@@ -1,5 +1,5 @@ Name: ddc-core-eval-Version: 0.3.2.1+Version: 0.4.1.1 License: MIT License-file: LICENSE Author: The Disciplined Disciple Compiler Strike Force@@ -19,14 +19,14 @@ Library Build-Depends: - base == 4.6.*,+ base >= 4.6 && < 4.8,+ array >= 0.4 && < 0.6, deepseq == 1.3.*, containers == 0.5.*,- array == 0.4.*, transformers == 0.3.*, mtl == 2.1.*,- ddc-base == 0.3.2.*,- ddc-core == 0.3.2.*+ ddc-base == 0.4.1.*,+ ddc-core == 0.4.1.* Exposed-modules: DDC.Core.Eval.Check@@ -43,6 +43,7 @@ -Wall -fno-warn-orphans -fno-warn-missing-signatures+ -fno-warn-missing-methods -fno-warn-unused-do-bind Extensions: