@@ -1,11 +1,12 @@
1−{-# LANGUAGE MagicHash, UnboxedTuples #-}
2−#if MIN_VERSION_GLASGOW_HASKELL(8,6,0,0)
3−{-# LANGUAGE GADTs #-}
1+{-# LANGUAGE UnboxedTuples, KindSignatures, DataKinds #-}
2+#ifdef PM36_HASKELL_SCRIPTING
3+{-# LANGUAGE MagicHash #-}
44#endif
55module ProjectM36.ScriptSession where
66
7+#ifdef PM36_HASKELL_SCRIPTING
78import ProjectM36.Error
8−
9+import GHC
910import Control.Exception
1011import Control.Monad
1112import System.IO.Error
@@ -16,8 +17,6 @@ import System.FilePath
1617import System.Info (os, arch)
1718import Data.Text (Text, unpack)
1819import Data.Maybe
19−
20−import GHC
2120import GHC.Paths (libdir)
2221#if __GLASGOW_HASKELL__ >= 800
2322import GHC.LanguageExtensions
@@ -36,25 +35,41 @@ import Unsafe.Coerce
3635#if __GLASGOW_HASKELL__ >= 802
3736import Type
3837#elif __GLASGOW_HASKELL__ >= 710
39−import Type hiding (pprTyThing)
38+import Type hiding (pprTyThing)
4039#else
4140#endif
42−
4341import GHC.Exts (addrToAny#)
4442import GHC.Ptr (Ptr(..))
4543import Encoding
44+#endif
45+
4646
4747data ScriptSession = ScriptSession {
48− hscEnv :: HscEnv,
48+#ifdef PM36_HASKELL_SCRIPTING
49+ hscEnv :: HscEnv,
4950 atomFunctionBodyType :: Type,
5051 dbcFunctionBodyType :: Type
52+#endif
5153 }
52−
53−newtype ScriptSessionError = ScriptSessionLoadError GhcException
54+
55+#ifdef PM36_HASKELL_SCRIPTING
56+data ScriptSessionError = ScriptSessionLoadError GhcException
57+ | ScriptingDisabled
5458 deriving (Show)
59+#else
60+data ScriptSessionError = ScriptingDisabled
61+ deriving (Show)
62+#endif
63+
64+data LoadSymbolError = LoadSymbolError
65+type ModName = String
66+type FuncName = String
5567
5668-- | Configure a GHC environment/session which we will use for all script compilation.
5769initScriptSession :: [String] -> IO (Either ScriptSessionError ScriptSession)
70+#if !defined(PM36_HASKELL_SCRIPTING)
71+initScriptSession _ = pure (Left ScriptingDisabled)
72+#else
5873initScriptSession ghcPkgPaths = do
5974 --for the sake of convenience, for developers' builds, include the local cabal sandbox package database and the cabal new-build package database
6075 eHomeDir <- tryJust (guard . isDoesNotExistError) getHomeDirectory
@@ -65,26 +80,26 @@ initScriptSession ghcPkgPaths = do
6580 let ghcVersion = projectVersion dflags
6681
6782 sandboxPkgPaths <- liftIO $ concat <$> mapM glob [
68− "./dist-newstyle/packagedb/ghc-" ++ ghcVersion,
83+ --"./dist-newstyle/packagedb/ghc-" ++ ghcVersion, --rely on cabal 3's ghc.environment install: "cabal install --lib project-m36"
6984 ".cabal-sandbox/*ghc-" ++ ghcVersion ++ "-packages.conf.d",
7085 ".stack-work/install/*/*/" ++ ghcVersion ++ "/pkgdb",
7186 ".stack-work/install/*/pkgdb/", --windows stack build
7287 "C:/sr/snapshots/b201cfe6/pkgdb", --windows stack build- ideally, we could run `stack path --snapshot-pkg-db, but this is sufficient to pass CI
73− homeDir </> ".stack/snapshots/*/*/" ++ ghcVersion ++ "/pkgdb",
74− homeDir </> ".cabal/store/ghc-" ++ ghcVersion ++ "/package.db"
88+ homeDir </> ".stack/snapshots/*/*/" ++ ghcVersion ++ "/pkgdb"
89+ --homeDir </> ".cabal/store/ghc-" ++ ghcVersion ++ "/package.db"
7590 ]
76−
91+
7792 let localPkgPaths = map PkgConfFile (ghcPkgPaths ++ sandboxPkgPaths)
78−
79− let dflags' = applyGopts . applyXopts $ dflags { hscTarget = HscInterpreted ,
80− ghcLink = LinkInMemory,
93+
94+ let dflags' = applyGopts . applyXopts $ dflags { hscTarget = HscInterpreted ,
95+ ghcLink = LinkInMemory,
8196 safeHaskell = Sf_Trustworthy,
8297 safeInfer = True,
8398 safeInferred = True,
8499 --verbosity = 3,
85−#if __GLASGOW_HASKELL__ >= 800
100+#if __GLASGOW_HASKELL__ >= 800
86101 trustFlags = map TrustPackage required_packages,
87−#endif
102+#endif
88103 packageFlags = packageFlags dflags ++ packages,
89104#if __GLASGOW_HASKELL__ >= 802
90105 packageDBFlags = map PackageDB localPkgPaths
@@ -97,11 +112,11 @@ initScriptSession ghcPkgPaths = do
97112 applyXopts flags = foldl xopt_set flags xopts
98113#if __GLASGOW_HASKELL__ >= 800
99114 xopts = [OverloadedStrings, ExtendedDefaultRules, ImplicitPrelude, ScopedTypeVariables]
100−#else
115+#else
101116 xopts = [Opt_OverloadedStrings, Opt_ExtendedDefaultRules, Opt_ImplicitPrelude, Opt_ScopedTypeVariables]
102117#endif
103118 gopts = [] --[Opt_DistrustAllPackages, Opt_PackageTrust]
104− required_packages = ["base",
119+ required_packages = ["base",
105120 "containers",
106121 "Glob",
107122 "directory",
@@ -123,13 +138,14 @@ initScriptSession ghcPkgPaths = do
123138 --liftIO $ traceShowM (showSDoc dflags' (ppr packages))
124139 _ <- setSessionDynFlags dflags'
125140 let safeImportDecl mn mQual = ImportDecl {
126−#if __GLASGOW_HASKELL__ >= 802
141+#if __GLASGOW_HASKELL__ >= 802
127142 ideclSourceSrc = NoSourceText,
128143#else
129144 ideclSourceSrc = Nothing,
130145#endif
131−#if MIN_VERSION_GLASGOW_HASKELL(8,6,0,0)
132− ideclExt = noExt,
146+
147+#if __GLASGOW_HASKELL__ >= 806
148+ ideclExt = NoExt,
133149#endif
134150 ideclName = noLoc mn,
135151 ideclPkgQual = Nothing,
@@ -140,6 +156,9 @@ initScriptSession ghcPkgPaths = do
140156 ideclAs = mQual,
141157 ideclHiding = Nothing
142158 }
159+#if __GLASGOW_HASKELL__ >= 806
160+ :: ImportDecl (GhcPass (c :: Pass))
161+#endif
143162 unqualifiedModules = map (\modn -> IIDecl $ safeImportDecl (mkModuleName modn) Nothing) [
144163 "Prelude",
145164 "Data.Map",
@@ -156,7 +175,7 @@ initScriptSession ghcPkgPaths = do
156175 mkModName = noLoc . mkModuleName
157176#else
158177 mkModName = mkModuleName
159−#endif
178+#endif
160179 qualifiedModules = map (\(modn, qualNam) -> IIDecl $ safeImportDecl (mkModuleName modn) (Just (mkModName qualNam))) [
161180 ("Data.Text", "T")
162181 ]
@@ -169,8 +188,8 @@ initScriptSession ghcPkgPaths = do
169188addImport :: String -> Ghc ()
170189addImport moduleNam = do
171190 ctx <- getContext
172− setContext ( (IIDecl $ simpleImportDecl (mkModuleName moduleNam)) : ctx )
173−
191+ setContext (IIDecl (simpleImportDecl (mkModuleName moduleNam)) : ctx)
192+
174193showType :: DynFlags -> Type -> String
175194showType dflags ty = showSDocForUser dflags alwaysQualify (pprTypeForUser ty)
176195
@@ -195,41 +214,36 @@ compileScript funcType script = do
195214 mErr <- typeCheckScript funcType script
196215 case mErr of
197216 Just err -> pure (Left err)
198− Nothing ->
217+ Nothing ->
199218 --catch exception here
200219 --we could potentially wrap the script with Atom pattern matching so that the script doesn't have to do it, but the change to an Atom ADT should make it easier. Still, it would be nice if the script didn't have to handle a list of arguments, for example.
201220 -- we can't use dynCompileExpr here because
202221 Right . unsafeCoerce <$> compileExpr sScript
203−
204−typeCheckScript :: Type -> Text -> Ghc (Maybe ScriptCompilationError)
222+
223+typeCheckScript :: Type -> Text -> Ghc (Maybe ScriptCompilationError)
205224typeCheckScript expectedType inp = do
206− dflags <- getSessionDynFlags
225+ dflags <- getSessionDynFlags
207226 --catch exception for SyntaxError
208227#if __GLASGOW_HASKELL__ >= 802
209− funcType <- GHC.exprType TM_Inst (unpack inp)
210−#else
228+ funcType <- GHC.exprType TM_Inst (unpack inp)
229+#else
211230 funcType <- GHC.exprType (unpack inp)
212231#endif
213− --liftIO $ putStrLn $ showType dflags expectedType ++ ":::" ++ showType dflags funcType
232+ --liftIO $ putStrLn $ showType dflags expectedType ++ ":::" ++ showType dflags funcType
214233 if eqType funcType expectedType then
215234 pure Nothing
216235 else
217236 pure (Just (TypeCheckCompilationError (showType dflags expectedType) (showType dflags funcType)))
218−
237+
219238mangleSymbol :: Maybe String -> String -> String -> String
220239mangleSymbol pkg module' valsym =
221240 prefixUnderscore ++
222241 maybe "" (\p -> zEncodeString p ++ "_") pkg ++
223242 zEncodeString module' ++ "_" ++ zEncodeString valsym ++ "_closure"
224−
225−type ModName = String
226−type FuncName = String
227−
228−data LoadSymbolError = LoadSymbolError
229243
230244loadFunction :: ModName -> FuncName -> FilePath -> IO (Either LoadSymbolError a)
231245loadFunction modName funcName objPath = do
232−#if __GLASGOW_HASKELL__ >= 802
246+#if __GLASGOW_HASKELL__ >= 802
233247 initObjLinker RetainCAFs
234248#else
235249 initObjLinker
@@ -241,8 +255,8 @@ loadFunction modName funcName objPath = do
241255 Nothing -> pure (Left LoadSymbolError)
242256 Just (Ptr addr) -> case addrToAny# addr of
243257 (# hval #) -> pure (Right hval)
244−
245−prefixUnderscore :: String
258+
259+prefixUnderscore :: String
246260prefixUnderscore =
247261 case (os,arch) of
248262 ("mingw32","x86_64") -> ""
@@ -251,3 +265,4 @@ prefixUnderscore =
251265 ("darwin",_) -> "_"
252266 ("cygwin",_) -> "_"
253267 _ -> ""
268+#endif