dynloader (empty) → 0.1.0
raw patch · 6 files changed
+167/−0 lines, 6 filesdep +basedep +dynloaderdep +ghcsetup-changed
Dependencies added: base, dynloader, ghc, ghc-paths, hspec
Files
- LICENSE +30/−0
- README.md +4/−0
- Setup.hs +2/−0
- dynloader.cabal +56/−0
- src/System/Plugins/Dynloader.hs +45/−0
- test/Spec.hs +30/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Takenoko (c) 2018++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Takenoko nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,4 @@+# dynloader++This is a simple library for dynamically loading other packages at runtime.+
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ dynloader.cabal view
@@ -0,0 +1,56 @@+cabal-version: 1.12++-- This file has been generated from package.yaml by hpack version 0.31.0.+--+-- see: https://github.com/sol/hpack+--+-- hash: 4fc18584d6c7dfe49bf1ca1c779df82d307cd1501a7e00c08a03b06777d4bf7c++name: dynloader+version: 0.1.0+synopsis: Dynamically runtime loading packages+description: This is a simple library for dynamically loading other packages at runtime. Please see the README on GitHub at <https://github.com/taqenoqo/dynloader#readme>+category: System+homepage: https://github.com/taqenoqo/dynloader#readme+bug-reports: https://github.com/taqenoqo/dynloader/issues+author: Taqenoqo+maintainer: ttaakkee@gmail.com+copyright: Copyright (c) 2018, Taqenoqo+license: BSD3+license-file: LICENSE+build-type: Simple+extra-source-files:+ README.md++source-repository head+ type: git+ location: https://github.com/taqenoqo/dynloader++library+ exposed-modules:+ System.Plugins.Dynloader+ other-modules:+ Paths_dynloader+ hs-source-dirs:+ src+ build-depends:+ base >=4.9 && <5+ , ghc >=8.4 && <8.7+ , ghc-paths >=0.1 && <0.2+ default-language: Haskell2010++test-suite dynloader-test+ type: exitcode-stdio-1.0+ main-is: Spec.hs+ other-modules:+ Paths_dynloader+ hs-source-dirs:+ test+ ghc-options: -threaded -rtsopts -with-rtsopts=-N+ build-depends:+ base >=4.9 && <5+ , dynloader+ , ghc >=8.4 && <8.7+ , ghc-paths >=0.1 && <0.2+ , hspec+ default-language: Haskell2010
+ src/System/Plugins/Dynloader.hs view
@@ -0,0 +1,45 @@+module System.Plugins.Dynloader (+ unsafeLoad,+ load+ ) where++import GHC hiding (ModuleName, load)+import GHC.Paths (libdir)+import DynFlags (PackageFlag(..), PackageArg(..), ModRenaming(..))+import Data.Dynamic (Dynamic)+import Unsafe.Coerce++-- |+-- e.g.+--+-- @+-- f <- unsafeload [] ["Prelude"] "(+)"+-- f 1 2 -- 3+-- @+unsafeLoad :: [PackageName] -> [ModuleName] -> Expression -> IO a+unsafeLoad pkgs mdls exp = runGhcT (Just libdir) $ do+ initGhc pkgs mdls+ r <- compileExpr exp+ return $ unsafeCoerce r++load :: [PackageName] -> [ModuleName] -> Expression -> IO Dynamic+load pkgs mdls exp = runGhcT (Just libdir) $ do+ initGhc pkgs mdls+ dynCompileExpr exp++type PackageName = String+type ModuleName = String+type Expression = String++initGhc :: GhcMonad m => [PackageName] -> [ModuleName] -> m ()+initGhc pkgs mdls = do+ initDynFlags+ setContext $ map (IIDecl . simpleImportDecl . mkModuleName) mdls+ where+ initDynFlags = do+ df <- getSessionDynFlags+ setSessionDynFlags df {+ hscTarget = HscInterpreted,+ ghcLink = LinkInMemory,+ packageFlags = [ExposePackage p (PackageArg p) (ModRenaming True []) | p <- pkgs]+ }
+ test/Spec.hs view
@@ -0,0 +1,30 @@+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE Rank2Types #-}++import System.Plugins.Dynloader+import Test.Hspec+import Data.Dynamic+import Data.Maybe++main :: IO ()+main = hspec $ do+ describe "unasfeLoad" $ do+ it "can load foreign value" $+ unsafeLoad [] [] "3" `shouldReturn` 3++ it "can load Prelude function" $+ do+ plus <- unsafeLoad [] ["Prelude"] "(+)"+ return $ plus 1 2++ `shouldReturn` 3++ describe "load" $+ it "can return Prelude data wraped in Dynamic" $+ do+ dyn <- load [] ["Prelude"] "Just True"+ let value = fromJust $ fromDynamic dyn+ return $ value++ `shouldReturn` Just True+