[Git][ghc/ghc][wip/js-staging] 2 commits: Remove shims and refactor Cpp

Sylvain Henry (@hsyl20) gitlab at gitlab.haskell.org
Tue Oct 11 19:31:17 UTC 2022



Sylvain Henry pushed to branch wip/js-staging at Glasgow Haskell Compiler / GHC


Commits:
5883d641 by Sylvain Henry at 2022-10-11T21:34:32+02:00
Remove shims and refactor Cpp

I've removed the use of js/rts.h and js/constants.h again. We generate
their contents at cpp time. Instead of wiring z-encoded strings into
these macros, we should derive them from wired-in Names so that they
stay correct in the future. Using wired-in Names as single source of
truth.

- - - - -
0015d2d9 by Sylvain Henry at 2022-10-11T21:34:32+02:00
Support RTS globals (used by GHC) and EISDIR

Did this while trying to fix CallArity1 (still failing)

- - - - -


26 changed files:

- compiler/GHC/Driver/Backend.hs
- compiler/GHC/Driver/Pipeline.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- − compiler/GHC/JS/Parser/Header.hs
- compiler/GHC/StgToJS/Linker/Linker.hs
- − compiler/GHC/StgToJS/Linker/Shims.hs
- compiler/GHC/StgToJS/Linker/Utils.hs
- + compiler/GHC/SysTools/Cpp.hs
- compiler/ghc.cabal.in
- libraries/base/jsbits/base.js
- libraries/base/jsbits/errno.js
- − rts/include/js/constants.h
- − rts/include/js/rts.h
- rts/js/arith.js
- rts/js/compact.js
- rts/js/environment.js
- + rts/js/globals.js
- rts/js/hscore.js
- rts/js/mem.js
- rts/js/object.js
- rts/js/rts.js
- rts/js/staticpointer.js
- rts/js/string.js
- rts/js/thread.js
- rts/js/weak.js
- rts/rts.cabal.in


Changes:

=====================================
compiler/GHC/Driver/Backend.hs
=====================================
@@ -960,7 +960,7 @@ Such a function may be applied in one of two ways:
     applyCDefs :: DefunctionalizedCDefs -> Logger -> DynFlags -> IO [String]
     @
 
-    Function `applyCDefs` is defined in module "GHC.Driver.Pipeline.Execute".
+    Function `applyCDefs` is defined in module "GHC.SysTools.Cpp".
 
 I don't love this solution, but defunctionalization is a standard
 thing, and it makes the meanings of the enumeration values clear.


=====================================
compiler/GHC/Driver/Pipeline.hs
=====================================
@@ -72,6 +72,7 @@ import GHC.Driver.Hooks
 import GHC.Platform.Ways
 
 import GHC.SysTools
+import GHC.SysTools.Cpp
 import GHC.Utils.TmpFs
 
 import GHC.Linker.ExtraObj


=====================================
compiler/GHC/Driver/Pipeline/Execute.hs
=====================================
@@ -48,6 +48,7 @@ import GHC.Utils.Error
 import Data.Maybe
 import GHC.CmmToLlvm.Mangler
 import GHC.SysTools
+import GHC.SysTools.Cpp
 import GHC.Utils.Panic.Plain
 import System.Directory
 import System.FilePath
@@ -61,7 +62,6 @@ import GHC.Iface.Make
 import Data.Time
 import GHC.Driver.Config.Parser
 import GHC.Parser.Header
-import qualified GHC.JS.Parser.Header as JSHeader
 import GHC.Data.StringBuffer
 import GHC.Types.SourceError
 import GHC.Unit.Finder
@@ -69,21 +69,19 @@ import GHC.Runtime.Loader
 import Data.IORef
 import GHC.Types.Name.Env
 import GHC.Platform.Ways
-import GHC.Platform.ArchOS
 import GHC.Driver.LlvmConfigCache (readLlvmConfigCache)
-import GHC.CmmToLlvm.Config (llvmVersionList, LlvmTarget (..), LlvmConfig (..))
+import GHC.CmmToLlvm.Config (LlvmTarget (..), LlvmConfig (..))
 import {-# SOURCE #-} GHC.Driver.Pipeline (compileForeign, compileEmptyStub)
 import GHC.Settings
 import System.IO
 import GHC.Linker.ExtraObj
 import GHC.Linker.Dynamic
-import Data.Version
 import GHC.Utils.Panic
 import GHC.Unit.Module.Env
 import GHC.Driver.Env.KnotVars
 import GHC.Driver.Config.Finder
 import GHC.Rename.Names
-import GHC.StgToJS.Object (isJsObjectFile)
+import GHC.StgToJS.Linker.Linker (embedJsFile)
 
 import Language.Haskell.Syntax.Module.Name
 
@@ -351,56 +349,14 @@ runAsPhase with_cpp pipe_env hsc_env location input_fn = do
 -- | Embed .js files into .o files
 runJsPhase :: PipeEnv -> HscEnv -> FilePath -> IO FilePath
 runJsPhase pipe_env hsc_env input_fn = do
-        let dflags     = hsc_dflags   hsc_env
-        let logger     = hsc_logger   hsc_env
-        let tmpfs      = hsc_tmpfs    hsc_env
-        let unit_env   = hsc_unit_env hsc_env
-
-        output_fn <- phaseOutputFilenameNew StopLn pipe_env hsc_env Nothing
-
-        -- if the input filename is the same as the output, then we've probably
-        -- generated the object ourselves, we leave the file alone
-        when (input_fn /= output_fn) $ do
-
-          -- the header lets the linker recognize processed JavaScript files
-          -- But don't add JavaScript header to object files!
-
-          is_js_obj <- if True
-                        then pure False
-                        else isJsObjectFile input_fn
-                        -- FIXME (Sylvain 2022-09): this call makes the
-                        -- testsuite go into a loop, I don't know why yet!
-                        -- Disabling it for now.
-
-          if is_js_obj
-            then copyWithHeader "" input_fn output_fn
-            else do
-              -- header appended to JS files stored as .o to recognize them.
-              let header = "//JavaScript\n"
-              jsFileNeedsCpp input_fn >>= \case
-                False -> copyWithHeader header input_fn output_fn
-                True  -> do
-                  -- run CPP on the input JS file
-                  tmp_fn <- newTempName logger tmpfs (tmpDir dflags) TFL_CurrentModule "js"
-                  doCpp logger
-                          tmpfs
-                          dflags
-                          unit_env
-                          (CppOpts
-                              { cppUseCc = True
-                              , cppLinePragmas = False
-                              })
-                          []
-                          input_fn
-                          tmp_fn
-                  copyWithHeader header tmp_fn output_fn
-
-        return output_fn
+  let dflags     = hsc_dflags   hsc_env
+  let logger     = hsc_logger   hsc_env
+  let tmpfs      = hsc_tmpfs    hsc_env
+  let unit_env   = hsc_unit_env hsc_env
 
-jsFileNeedsCpp :: FilePath -> IO Bool
-jsFileNeedsCpp fn = do
-  opts <- JSHeader.getOptionsFromJsFile fn
-  pure (JSHeader.CPP `elem` opts)
+  output_fn <- phaseOutputFilenameNew StopLn pipe_env hsc_env Nothing
+  embedJsFile logger dflags tmpfs unit_env input_fn output_fn
+  return output_fn
 
 
 applyAssemblerInfoGetter
@@ -1030,153 +986,6 @@ llvmOptions llvm_config dflags =
                 _           -> ""
 
 
--- Note [Filepaths and Multiple Home Units]
-offsetIncludePaths :: DynFlags -> IncludeSpecs -> IncludeSpecs
-offsetIncludePaths dflags (IncludeSpecs incs quotes impl) =
-     let go = map (augmentByWorkingDirectory dflags)
-     in IncludeSpecs (go incs) (go quotes) (go impl)
--- -----------------------------------------------------------------------------
--- Running CPP
-
-data CppOpts = CppOpts
-  { cppUseCc       :: !Bool -- ^ Use "cc -E" as preprocessor, otherwise use "cpp"
-  , cppLinePragmas :: !Bool -- ^ Enable generation of LINE pragmas
-  }
-
--- | Run CPP
---
--- UnitEnv is needed to compute MIN_VERSION macros
-doCpp :: Logger -> TmpFs -> DynFlags -> UnitEnv -> CppOpts -> [Option] -> FilePath -> FilePath -> IO ()
-doCpp logger tmpfs dflags unit_env opts extra_opts input_fn output_fn = do
-    let hscpp_opts = picPOpts dflags
-    let cmdline_include_paths = offsetIncludePaths dflags (includePaths dflags)
-    let unit_state = ue_units unit_env
-    pkg_include_dirs <- mayThrowUnitErr
-                        (collectIncludeDirs <$> preloadUnitsInfo unit_env)
-    -- MP: This is not quite right, the headers which are supposed to be installed in
-    -- the package might not be the same as the provided include paths, but it's a close
-    -- enough approximation for things to work. A proper solution would be to have to declare which paths should
-    -- be propagated to dependent packages.
-    let home_pkg_deps =
-         [homeUnitEnv_dflags . ue_findHomeUnitEnv uid $ unit_env | uid <- ue_transitiveHomeDeps (ue_currentUnit unit_env) unit_env]
-        dep_pkg_extra_inputs = [offsetIncludePaths fs (includePaths fs) | fs <- home_pkg_deps]
-
-    let include_paths_global = foldr (\ x xs -> ("-I" ++ x) : xs) []
-          (includePathsGlobal cmdline_include_paths ++ pkg_include_dirs
-                                                    ++ concatMap includePathsGlobal dep_pkg_extra_inputs)
-    let include_paths_quote = foldr (\ x xs -> ("-iquote" ++ x) : xs) []
-          (includePathsQuote cmdline_include_paths ++
-           includePathsQuoteImplicit cmdline_include_paths)
-    let include_paths = include_paths_quote ++ include_paths_global
-
-    let verbFlags = getVerbFlags dflags
-
-    let cpp_prog args
-          | cppUseCc opts = GHC.SysTools.runCc Nothing logger tmpfs dflags
-                                               (GHC.SysTools.Option "-E" : args)
-          | otherwise     = GHC.SysTools.runCpp logger dflags args
-
-    let platform   = targetPlatform dflags
-        targetArch = stringEncodeArch $ platformArch platform
-        targetOS = stringEncodeOS $ platformOS platform
-        isWindows = platformOS platform == OSMinGW32
-    let target_defs =
-          [ "-D" ++ HOST_OS     ++ "_BUILD_OS",
-            "-D" ++ HOST_ARCH   ++ "_BUILD_ARCH",
-            "-D" ++ targetOS    ++ "_HOST_OS",
-            "-D" ++ targetArch  ++ "_HOST_ARCH" ]
-        -- remember, in code we *compile*, the HOST is the same our TARGET,
-        -- and BUILD is the same as our HOST.
-
-    let io_manager_defs =
-          [ "-D__IO_MANAGER_WINIO__=1" | isWindows ] ++
-          [ "-D__IO_MANAGER_MIO__=1"               ]
-
-    let sse_defs =
-          [ "-D__SSE__"      | isSseEnabled      platform ] ++
-          [ "-D__SSE2__"     | isSse2Enabled     platform ] ++
-          [ "-D__SSE4_2__"   | isSse4_2Enabled   dflags ]
-
-    let avx_defs =
-          [ "-D__AVX__"      | isAvxEnabled      dflags ] ++
-          [ "-D__AVX2__"     | isAvx2Enabled     dflags ] ++
-          [ "-D__AVX512CD__" | isAvx512cdEnabled dflags ] ++
-          [ "-D__AVX512ER__" | isAvx512erEnabled dflags ] ++
-          [ "-D__AVX512F__"  | isAvx512fEnabled  dflags ] ++
-          [ "-D__AVX512PF__" | isAvx512pfEnabled dflags ]
-
-    backend_defs <- applyCDefs (backendCDefs $ backend dflags) logger dflags
-
-    let th_defs = [ "-D__GLASGOW_HASKELL_TH__" ]
-    -- Default CPP defines in Haskell source
-    ghcVersionH <- getGhcVersionPathName dflags unit_env
-    let hsSourceCppOpts = [ "-include", ghcVersionH ]
-
-    -- MIN_VERSION macros
-    let uids = explicitUnits unit_state
-        pkgs = mapMaybe (lookupUnit unit_state . fst) uids
-    mb_macro_include <-
-        if not (null pkgs) && gopt Opt_VersionMacros dflags
-            then do macro_stub <- newTempName logger tmpfs (tmpDir dflags) TFL_CurrentModule "h"
-                    writeFile macro_stub (generatePackageVersionMacros pkgs)
-                    -- Include version macros for every *exposed* package.
-                    -- Without -hide-all-packages and with a package database
-                    -- size of 1000 packages, it takes cpp an estimated 2
-                    -- milliseconds to process this file. See #10970
-                    -- comment 8.
-                    return [GHC.SysTools.FileOption "-include" macro_stub]
-            else return []
-
-    let line_pragmas
-          | cppLinePragmas opts = [] -- on by default
-          | otherwise           = [GHC.SysTools.Option "-P"] -- disable LINE markers
-
-    cpp_prog       (   map GHC.SysTools.Option verbFlags
-                    ++ map GHC.SysTools.Option include_paths
-                    ++ map GHC.SysTools.Option hsSourceCppOpts
-                    ++ map GHC.SysTools.Option target_defs
-                    ++ map GHC.SysTools.Option backend_defs
-                    ++ map GHC.SysTools.Option th_defs
-                    ++ map GHC.SysTools.Option hscpp_opts
-                    ++ map GHC.SysTools.Option sse_defs
-                    ++ map GHC.SysTools.Option avx_defs
-                    ++ map GHC.SysTools.Option io_manager_defs
-                    ++ mb_macro_include
-                    ++ extra_opts
-                    ++ line_pragmas
-        -- Set the language mode to assembler-with-cpp when preprocessing. This
-        -- alleviates some of the C99 macro rules relating to whitespace and the hash
-        -- operator, which we tend to abuse. Clang in particular is not very happy
-        -- about this.
-                    ++ [ GHC.SysTools.Option     "-x"
-                       , GHC.SysTools.Option     "assembler-with-cpp"
-                       , GHC.SysTools.Option     input_fn
-        -- We hackily use Option instead of FileOption here, so that the file
-        -- name is not back-slashed on Windows.  cpp is capable of
-        -- dealing with / in filenames, so it works fine.  Furthermore
-        -- if we put in backslashes, cpp outputs #line directives
-        -- with *double* backslashes.   And that in turn means that
-        -- our error messages get double backslashes in them.
-        -- In due course we should arrange that the lexer deals
-        -- with these \\ escapes properly.
-                       , GHC.SysTools.Option     "-o"
-                       , GHC.SysTools.FileOption "" output_fn
-                       ])
-
-applyCDefs :: DefunctionalizedCDefs -> Logger -> DynFlags -> IO [String]
-applyCDefs NoCDefs _ _ = return []
-applyCDefs LlvmCDefs logger dflags = do
-    llvmVer <- figureLlvmVersion logger dflags
-    return $ case fmap llvmVersionList llvmVer of
-               Just [m] -> [ "-D__GLASGOW_HASKELL_LLVM__=" ++ format (m,0) ]
-               Just (m:n:_) -> [ "-D__GLASGOW_HASKELL_LLVM__=" ++ format (m,n) ]
-               _ -> []
-  where
-    format (major, minor)
-      | minor >= 100 = error "backendCDefs: Unsupported minor version"
-      | otherwise = show (100 * major + minor :: Int) -- Contract is Int
-
-
 -- | What phase to run after one of the backend code generators has run
 hscPostBackendPhase :: HscSource -> Backend -> Phase
 hscPostBackendPhase HsBootFile _    =  StopLn
@@ -1327,36 +1136,6 @@ linkDynLibCheck logger tmpfs dflags unit_env o_files dep_units = do
 
 
 
--- ---------------------------------------------------------------------------
--- Macros (cribbed from Cabal)
-
-generatePackageVersionMacros :: [UnitInfo] -> String
-generatePackageVersionMacros pkgs = concat
-  -- Do not add any C-style comments. See #3389.
-  [ generateMacros "" pkgname version
-  | pkg <- pkgs
-  , let version = unitPackageVersion pkg
-        pkgname = map fixchar (unitPackageNameString pkg)
-  ]
-
-fixchar :: Char -> Char
-fixchar '-' = '_'
-fixchar c   = c
-
-generateMacros :: String -> String -> Version -> String
-generateMacros prefix name version =
-  concat
-  ["#define ", prefix, "VERSION_",name," ",show (showVersion version),"\n"
-  ,"#define MIN_", prefix, "VERSION_",name,"(major1,major2,minor) (\\\n"
-  ,"  (major1) <  ",major1," || \\\n"
-  ,"  (major1) == ",major1," && (major2) <  ",major2," || \\\n"
-  ,"  (major1) == ",major1," && (major2) == ",major2," && (minor) <= ",minor,")"
-  ,"\n\n"
-  ]
-  where
-    (major1:major2:minor:_) = map show (versionBranch version ++ repeat 0)
-
-
 -- -----------------------------------------------------------------------------
 -- Misc.
 
@@ -1367,22 +1146,6 @@ touchObjectFile logger dflags path = do
   createDirectoryIfMissing True $ takeDirectory path
   GHC.SysTools.touch logger dflags "Touching object file" path
 
--- | Find out path to @ghcversion.h@ file
-getGhcVersionPathName :: DynFlags -> UnitEnv -> IO FilePath
-getGhcVersionPathName dflags unit_env = do
-  candidates <- case ghcVersionFile dflags of
-    Just path -> return [path]
-    Nothing -> do
-        ps <- mayThrowUnitErr (preloadUnitsInfo' unit_env [rtsUnitId])
-        return ((</> "ghcversion.h") <$> collectIncludeDirs ps)
-
-  found <- filterM doesFileExist candidates
-  case found of
-      []    -> throwGhcExceptionIO (InstallationError
-                                    ("ghcversion.h missing; tried: "
-                                      ++ intercalate ", " candidates))
-      (x:_) -> return x
-
 -- Note [-fPIC for assembler]
 -- ~~~~~~~~~~~~~~~~~~~~~~~~~~
 -- When compiling .c source file GHC's driver pipeline basically


=====================================
compiler/GHC/JS/Parser/Header.hs deleted
=====================================
@@ -1,54 +0,0 @@
-{-# LANGUAGE MultiWayIf #-}
-{-# LANGUAGE OverloadedStrings #-}
-
------------------------------------------------------------------------------
---
--- | Parsing the top of a JS source file to get its options.
---
------------------------------------------------------------------------------
-
-module GHC.JS.Parser.Header
-   ( getOptionsFromJsFile
-   , JSOption(..)
-   )
-where
-
-import GHC.Prelude
-
-import System.IO
-import Data.Char (isSpace)
-import qualified Data.ByteString as B
-import qualified Control.Exception as Exception
-
-getOptionsFromJsFile :: FilePath      -- ^ Input file
-                     -> IO [JSOption] -- ^ Parsed options, if any.
-getOptionsFromJsFile filename
-    = Exception.bracket
-              (openBinaryFile filename ReadMode)
-              hClose
-              getJsOptions
-
-data JSOption = CPP deriving (Eq, Ord)
-
-getJsOptions :: Handle -> IO [JSOption]
-getJsOptions handle = do
-  hSetEncoding handle utf8
-  prefix' <- B.hGet handle prefixLen
-  if prefix == prefix'
-  then parseJsOptions <$> hGetLine handle
-  else pure []
- where
-  prefix :: B.ByteString
-  prefix = "//#OPTIONS:"
-  prefixLen = B.length prefix
-
-parseJsOptions :: String -> [JSOption]
-parseJsOptions xs = go xs
-  where
-    trim = reverse . dropWhile isSpace . reverse . dropWhile isSpace
-    go [] = []
-    go xs = let (tok, rest) = break (== ',') xs
-                tok' = trim tok
-                rest' = drop 1 rest
-            in  if | tok' == "CPP" -> CPP : go rest'
-                   | otherwise     -> go rest'


=====================================
compiler/GHC/StgToJS/Linker/Linker.hs
=====================================
@@ -22,6 +22,7 @@
 
 module GHC.StgToJS.Linker.Linker
   ( jsLinkBinary
+  , embedJsFile
   )
 where
 
@@ -33,6 +34,8 @@ import GHC.JS.Syntax
 
 import GHC.Driver.Session (DynFlags(..))
 import Language.Haskell.Syntax.Module.Name
+import GHC.SysTools.Cpp
+import GHC.SysTools
 
 import GHC.Linker.Static.Utils (exeFileName)
 
@@ -58,8 +61,8 @@ import GHC.Utils.Error
 import GHC.Utils.Logger (Logger, logVerbAtLeast)
 import GHC.Utils.Binary
 import qualified GHC.Utils.Ppr as Ppr
-import GHC.Utils.CliOption
 import GHC.Utils.Monad
+import GHC.Utils.TmpFs
 
 import qualified GHC.SysTools.Ar          as Ar
 
@@ -794,3 +797,70 @@ readDepsFromObj = \case
     readObjectDeps file >>= \case
       Nothing   -> pure Nothing
       Just deps -> pure $ Just (deps,ObjectFile file)
+
+
+-- | Embed a JS file into a .o file
+--
+-- The JS file is merely copied into a .o file with an additional header
+-- ("//Javascript") in order to be recognized later on.
+--
+-- JS files may contain option pragmas of the form: //#OPTIONS:
+-- For now, only the CPP option is supported. If the CPP option is set, we
+-- append some common CPP definitions to the file and call cpp on it.
+embedJsFile :: Logger -> DynFlags -> TmpFs -> UnitEnv -> FilePath -> FilePath -> IO ()
+embedJsFile logger dflags tmpfs unit_env input_fn output_fn = do
+  let profiling  = False -- FIXME: add support for profiling way
+
+  -- if the input filename is the same as the output, then we've probably
+  -- generated the object ourselves, we leave the file alone
+  when (input_fn /= output_fn) $ do
+
+    -- the header lets the linker recognize processed JavaScript files
+    -- But don't add JavaScript header to object files!
+
+    is_js_obj <- if True
+                  then pure False
+                  else isJsObjectFile input_fn
+                  -- FIXME (Sylvain 2022-09): this call makes the
+                  -- testsuite go into a loop, I don't know why yet!
+                  -- Disabling it for now.
+
+    if is_js_obj
+      then copyWithHeader "" input_fn output_fn
+      else do
+        -- header appended to JS files stored as .o to recognize them.
+        let header = "//JavaScript\n"
+        jsFileNeedsCpp input_fn >>= \case
+          False -> copyWithHeader header input_fn output_fn
+          True  -> do
+
+            -- append common CPP definitions to the .js file.
+            -- They define macros that avoid directly wiring zencoded names
+            -- in RTS JS files
+            pp_fn <- newTempName logger tmpfs (tmpDir dflags) TFL_CurrentModule "js"
+            payload <- B.readFile input_fn
+            B.writeFile pp_fn (commonCppDefs profiling <> payload)
+
+            -- run CPP on the input JS file
+            js_fn <- newTempName logger tmpfs (tmpDir dflags) TFL_CurrentModule "js"
+            let
+              cpp_opts = CppOpts
+                { cppUseCc       = True
+                , cppLinePragmas = False -- LINE pragmas aren't JS compatible
+                }
+              extra_opts = []
+            doCpp logger
+                    tmpfs
+                    dflags
+                    unit_env
+                    cpp_opts
+                    extra_opts
+                    pp_fn
+                    js_fn
+            -- add header to recognize the object as a JS file
+            copyWithHeader header js_fn output_fn
+
+jsFileNeedsCpp :: FilePath -> IO Bool
+jsFileNeedsCpp fn = do
+  opts <- getOptionsFromJsFile fn
+  pure (CPP `elem` opts)


=====================================
compiler/GHC/StgToJS/Linker/Shims.hs deleted
=====================================
@@ -1,195 +0,0 @@
-{-# LANGUAGE DerivingStrategies #-}
-{-# LANGUAGE DeriveFunctor      #-}
-{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-{-# LANGUAGE TupleSections      #-}
-
------------------------------------------------------------------------------
--- |
--- Module      :  GHC.StgToJS.Linker.Shims
--- Copyright   :  (c) The University of Glasgow 2001
--- License     :  BSD-style (see the file LICENSE)
---
--- Maintainer  :  Jeffrey Young  <jeffrey.young at iohk.io>
---                Luite Stegeman <luite.stegeman at iohk.io>
---                Sylvain Henry  <sylvain.henry at iohk.io>
---                Josh Meredith  <josh.meredith at iohk.io>
--- Stability   :  experimental
---
--- A small DSL to handle Shim files in the JS backend, mostly used in
--- 'GHC.StgToJS.Linker.Linker'
---
------------------------------------------------------------------------------
-module GHC.StgToJS.Linker.Shims
-  ( Shim()
-  , withShim
-  , parseShim
-  , readShimFiles
-  , tryReadShimFile
-  , streamShims
-  ) where
-
-import           GHC.StgToJS.Linker.Utils
-
-import           System.FilePath
-import           GHC.Driver.Session
-import           GHC.Driver.Pipeline.Execute (doCpp, CppOpts(..))
-
-import           GHC.Unit.Env
-import           GHC.Utils.TmpFs
-import           GHC.Utils.Logger
-import           GHC.Utils.Panic
-
-import           Data.Foldable (toList)
-import qualified Data.ByteString as B
-import           Data.Set  (Set)
-import qualified Data.Set  as Set
-
-import           Prelude
-
--- | A sum type to represent shims. Its sole purpose is to guarentee the
--- ordering of shims during link time. This makes it much harder to compile the
--- js-backend if the link ordering of shims is wrong. Each data constructor
--- represents a single shim file located in either @JS_RTS_PATH@ or
--- @JS_BASE_PATH at . See 'link'' for the call site.
---
--- ** Invariant: The order of data constructors in 'Shim'' determines the shim
---    link time ordering and there is a one-to-one correspondance between each
---    shim file and each data constructor
-type Shim = Shim' B.ByteString
-
-newtype Shim' a = Shim' { unShim :: (ShimLbl, a) }
-    deriving newtype Functor
-
--- | projections from Shims; project the shim label tag
--- shimLabel :: Shim -> ShimLbl
--- shimLabel = fst . unShim
-
--- | projections from Shims, project the payload
-shimPayload :: Shim' a -> a
-shimPayload = snd . unShim
-
--- | Take a shim and modify the payload, note that the shim label cannot change
--- as this might invalidate the shim invariant
-withShim :: Shim' a -> (a -> IO b) -> IO (Shim' b)
-withShim (Shim' (lbl, payload)) f = Shim' . (lbl,) <$> f payload
-
-
-instance Eq (Shim' a) where
-  (Shim' (l,_)) == (Shim' (r,_)) = l == r
-
-instance Ord (Shim' a) where
-  (Shim' (l,_)) `compare` (Shim' (r,_)) = l `compare` r
-
--- | A tag to label shim payloads, the ordering dictates the ordering shim files
--- are linked.
-data ShimLbl
-    -- Platform must be loaded quite early as it sets h$isNode which is used by
-    -- other shims (e.g. ShEnvironment)
-  = ShPlatform
-  | ShStructs
-  | ShProfiling
-  | ShRts
-  | ShGc
-  | ShArith
-  | ShCompact
-  | ShDebug
-  | ShEnum
-  | ShEnvironment
-  | ShErrno
-  | ShGoog
-  | ShHsCore
-  | ShMd5
-  | ShMem
-  | ShNodeExports
-  | ShObject
-  | ShStablePtr
-  | ShStaticPtr
-  | ShStm
-  | ShString
-  | ShThread
-  | ShUnicode
-  | ShVerify
-  | ShWeak
-  | ShBase
-  deriving (Eq, Ord)
-
--- | Given a file path, check that the file is a shim file and construct a Shim
--- value if so. This is the sole exported constructor for a Shim type.
-parseShim :: FilePath -> IO Shim
-parseShim f = let shimFn = takeFileName f
-              in case shimFn of
-                   "rts.js.pp"           ->  (Shim' . (ShRts,))          <$> B.readFile f
-                   "gc.js.pp"            ->  (Shim' . (ShGc,))           <$> B.readFile f
-                   "arith.js.pp"         ->  (Shim' . (ShArith,))        <$> B.readFile f
-                   "compact.js.pp"       ->  (Shim' . (ShCompact,))      <$> B.readFile f
-                   "debug.js.pp"         ->  (Shim' . (ShDebug,))        <$> B.readFile f
-                   "enum.js.pp"          ->  (Shim' . (ShEnum,))         <$> B.readFile f
-                   "environment.js.pp"   ->  (Shim' . (ShEnvironment,))  <$> B.readFile f
-                   "errno.js.pp"         ->  (Shim' . (ShErrno,))        <$> B.readFile f
-                   "goog.js"             ->  (Shim' . (ShGoog,))         <$> B.readFile f
-                   "hscore.js.pp"        ->  (Shim' . (ShHsCore,))       <$> B.readFile f
-                   "md5.js"              ->  (Shim' . (ShMd5,))          <$> B.readFile f
-                   "mem.js.pp"           ->  (Shim' . (ShMem,))          <$> B.readFile f
-                   "node-exports.js"     ->  (Shim' . (ShNodeExports,))  <$> B.readFile f
-                   "object.js.pp"        ->  (Shim' . (ShObject,))       <$> B.readFile f
-                   "platform.js.pp"      ->  (Shim' . (ShPlatform,))     <$> B.readFile f
-                   "profiling.js.pp"     ->  (Shim' . (ShProfiling,))    <$> B.readFile f
-                   "stableptr.js.pp"     ->  (Shim' . (ShStablePtr,))    <$> B.readFile f
-                   "staticpointer.js.pp" ->  (Shim' . (ShStaticPtr,))    <$> B.readFile f
-                   "stm.js.pp"           ->  (Shim' . (ShStm,))          <$> B.readFile f
-                   "string.js.pp"        ->  (Shim' . (ShString,))       <$> B.readFile f
-                   "structs.js.pp"       ->  (Shim' . (ShStructs,))      <$> B.readFile f
-                   "thread.js.pp"        ->  (Shim' . (ShThread,))       <$> B.readFile f
-                   "unicode.js"          ->  (Shim' . (ShUnicode,))      <$> B.readFile f
-                   "verify.js.pp"        ->  (Shim' . (ShVerify,))       <$> B.readFile f
-                   "weak.js.pp"          ->  (Shim' . (ShWeak,))         <$> B.readFile f
-                   "base.js.pp"          ->  (Shim' . (ShBase,))         <$> B.readFile f
-                   other                 -> panic $
-                                            "parseShim: unrecognized shim file: " ++ show other
-
--- | Convert any Foldable thing that holds shims into a stream of shim payloads.
--- This function frequently used in concert with 'Data.ByteString.fromChunks' in
--- 'GHC.StgToJS.Linker.Linker'
-streamShims :: Foldable f => f Shim -> [B.ByteString]
-streamShims = fmap shimPayload . toList
-
--- | read a sequence of possible shim files into a Set of shims. The set is
--- purposefully chosen to ensure a stable and order preserving container.
-readShimFiles :: Logger -> TmpFs -> DynFlags -> UnitEnv -> [FilePath] -> IO (Set Shim)
-readShimFiles logger tmpfs dflags unit_env =
-  fmap Set.fromList . mapM (tryReadShimFile logger tmpfs dflags unit_env)
-
--- | Attempt to read a shim file. This function may panic if the shim file
--- cannot be parsed to an expected shim file as defined by the 'Shim' type.
-tryReadShimFile :: Logger -> TmpFs -> DynFlags -> UnitEnv -> FilePath -> IO Shim
-tryReadShimFile logger tmpfs dflags unit_env file = do
-  if needsCpp file
-  then do
-    let profiling = False
-        cpp_opts = CppOpts
-          { cppUseCc       = True
-          , cppLinePragmas = False -- LINE pragmas aren't JS compatible
-          }
-        extra_opts = []
-
-    -- load the shim into memory
-    shim   <- parseShim file
-    -- make a temp file for doCpp
-    infile <- newTempName logger tmpfs (tmpDir dflags) TFL_CurrentModule "jsppx"
-
-    withShim shim $ \payload ->
-        do -- preparation: append common CPP definitions to the .pp file.
-           B.writeFile infile $ (commonCppDefs profiling) <> payload
-           outfile <- newTempName logger tmpfs (tmpDir dflags) TFL_CurrentModule "jspp"
-           -- do the business
-           doCpp logger tmpfs dflags unit_env cpp_opts extra_opts infile outfile
-           B.readFile outfile
-  else parseShim file
-
--- | Test if file has ".pp" extension
---
--- running the C preprocessor on JS files is a bit fragile
--- and breaks in some situations. Therefore we only preprocess
--- files with .pp extension, for example lib.js.pp
-needsCpp :: FilePath -> Bool
-needsCpp file = "pp" `isExtensionOf` file


=====================================
compiler/GHC/StgToJS/Linker/Utils.hs
=====================================
@@ -1,4 +1,5 @@
 {-# LANGUAGE OverloadedStrings  #-}
+{-# LANGUAGE MultiWayIf  #-}
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  GHC.StgToJS.Linker.Utils
@@ -15,13 +16,20 @@
 --
 -----------------------------------------------------------------------------
 
-module GHC.StgToJS.Linker.Utils where
+module GHC.StgToJS.Linker.Utils
+  ( getOptionsFromJsFile
+  , JSOption(..)
+  , jsExeFileName
+  , getInstalledPackageLibDirs
+  , getInstalledPackageHsLibs
+  , commonCppDefs
+  )
+where
 
 import           System.FilePath
 import qualified Data.ByteString as B
 import qualified Data.ByteString.Char8 as Char8
 import           Data.ByteString (ByteString)
-import           System.IO (withBinaryFile, IOMode(WriteMode))
 
 import          GHC.Driver.Session
 import          GHC.Settings.Config (cProjectVersion)
@@ -36,6 +44,10 @@ import           Prelude
 import GHC.Platform
 import Data.List (isPrefixOf)
 import System.Directory (createDirectoryIfMissing)
+import System.IO
+import Data.Char (isSpace)
+import qualified Data.ByteString as B
+import qualified Control.Exception as Exception
 
 -- | Given a FilePath and payload, write a file to disk creating any directories
 -- along the way if needed.
@@ -145,24 +157,6 @@ genCommonCppDefs profiling = mconcat
       then "#define MK_PTR(val,offset) (h$c2(h$baseZCGHCziPtrziPtr_con_e, (val), (offset), h$CCS_SYSTEM))\n"
       else "#define MK_PTR(val,offset) (h$c2(h$baseZCGHCziPtrziPtr_con_e, (val), (offset)))\n"
 
-  -- GHC.Integer.GMP.Internals
-  , "#define IS_INTEGER_S(cl) ((cl).f === h$integerzmwiredzminZCGHCziIntegerziTypeziSzh_con_e)\n"
-  , "#define IS_INTEGER_Jp(cl) ((cl).f === h$integerzmwiredzminZCGHCziIntegerziTypeziJpzh_con_e)\n"
-  , "#define IS_INTEGER_Jn(cl) ((cl).f === h$integerzmwiredzminZCGHCziIntegerziTypeziJnzh_con_e)\n"
-  , "#define INTEGER_S_DATA(cl) ((cl).d1)\n"
-  , "#define INTEGER_J_DATA(cl) ((cl).d1)\n"
-  , if profiling
-      then mconcat
-        [ "#define MK_INTEGER_S(iii) (h$c1(h$integerzmwiredzminZCGHCziIntegerziTypeziSzh_con_e, (iii), h$CCS_SYSTEM));\n"
-        , "#define MK_INTEGER_Jp(iii) (h$c1(h$integerzmwiredzminZCGHCziIntegerziTypeziJpzh_con_e, (iii), h$CCS_SYSTEM));\n"
-        , "#define MK_INTEGER_Jn(iii) (h$c1(h$integerzmwiredzminZCGHCziIntegerziTypeziJnzh_con_e, (iii), h$CCS_SYSTEM));\n"
-        ]
-      else mconcat
-        [ "#define MK_INTEGER_S(iii) (h$c1(h$integerzmwiredzminZCGHCziIntegerziTypeziSzh_con_e, (iii)));\n"
-        , "#define MK_INTEGER_Jp(iii) (h$c1(h$integerzmwiredzminZCGHCziIntegerziTypeziJpzh_con_e, (iii)));\n"
-        , "#define MK_INTEGER_Jn(iii) (h$c1(h$integerzmwiredzminZCGHCziIntegerziTypeziJnzh_con_e, (iii)));\n"
-        ]
-
   -- Data.Maybe.Maybe
   , "#define HS_NOTHING h$baseZCGHCziMaybeziNothing\n"
   , "#define IS_NOTHING(cl) ((cl).f === h$baseZCGHCziMaybeziNothing_con_e)\n"
@@ -297,3 +291,38 @@ jsExeFileName dflags
     dropPrefix prefix xs
       | prefix `isPrefixOf` xs = drop (length prefix) xs
       | otherwise              = xs
+
+
+-- | Parse option pragma in JS file
+getOptionsFromJsFile :: FilePath      -- ^ Input file
+                     -> IO [JSOption] -- ^ Parsed options, if any.
+getOptionsFromJsFile filename
+    = Exception.bracket
+              (openBinaryFile filename ReadMode)
+              hClose
+              getJsOptions
+
+data JSOption = CPP deriving (Eq, Ord)
+
+getJsOptions :: Handle -> IO [JSOption]
+getJsOptions handle = do
+  hSetEncoding handle utf8
+  prefix' <- B.hGet handle prefixLen
+  if prefix == prefix'
+  then parseJsOptions <$> hGetLine handle
+  else pure []
+ where
+  prefix :: B.ByteString
+  prefix = "//#OPTIONS:"
+  prefixLen = B.length prefix
+
+parseJsOptions :: String -> [JSOption]
+parseJsOptions xs = go xs
+  where
+    trim = reverse . dropWhile isSpace . reverse . dropWhile isSpace
+    go [] = []
+    go xs = let (tok, rest) = break (== ',') xs
+                tok' = trim tok
+                rest' = drop 1 rest
+            in  if | tok' == "CPP" -> CPP : go rest'
+                   | otherwise     -> go rest'


=====================================
compiler/GHC/SysTools/Cpp.hs
=====================================
@@ -0,0 +1,235 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE LambdaCase #-}
+
+#include <ghcplatform.h>
+
+module GHC.SysTools.Cpp
+  ( doCpp
+  , CppOpts (..)
+  , getGhcVersionPathName
+  , applyCDefs
+  , offsetIncludePaths
+  )
+where
+
+import GHC.Prelude
+import GHC.Driver.Session
+import GHC.Driver.Backend
+import GHC.CmmToLlvm.Config
+import GHC.Platform
+import GHC.Platform.ArchOS
+
+import GHC.SysTools
+
+import GHC.Unit.Env
+import GHC.Unit.Info
+import GHC.Unit.State
+import GHC.Unit.Types
+
+import GHC.Utils.Logger
+import GHC.Utils.TmpFs
+import GHC.Utils.Panic
+
+import Data.Version
+import Data.List (intercalate)
+import Data.Maybe
+
+import Control.Monad
+
+import System.Directory
+import System.FilePath
+
+data CppOpts = CppOpts
+  { cppUseCc       :: !Bool -- ^ Use "cc -E" as preprocessor, otherwise use "cpp"
+  , cppLinePragmas :: !Bool -- ^ Enable generation of LINE pragmas
+  }
+
+-- | Run CPP
+--
+-- UnitEnv is needed to compute MIN_VERSION macros
+doCpp :: Logger -> TmpFs -> DynFlags -> UnitEnv -> CppOpts -> [Option] -> FilePath -> FilePath -> IO ()
+doCpp logger tmpfs dflags unit_env opts extra_opts input_fn output_fn = do
+    let hscpp_opts = picPOpts dflags
+    let cmdline_include_paths = offsetIncludePaths dflags (includePaths dflags)
+    let unit_state = ue_units unit_env
+    pkg_include_dirs <- mayThrowUnitErr
+                        (collectIncludeDirs <$> preloadUnitsInfo unit_env)
+    -- MP: This is not quite right, the headers which are supposed to be installed in
+    -- the package might not be the same as the provided include paths, but it's a close
+    -- enough approximation for things to work. A proper solution would be to have to declare which paths should
+    -- be propagated to dependent packages.
+    let home_pkg_deps =
+         [homeUnitEnv_dflags . ue_findHomeUnitEnv uid $ unit_env | uid <- ue_transitiveHomeDeps (ue_currentUnit unit_env) unit_env]
+        dep_pkg_extra_inputs = [offsetIncludePaths fs (includePaths fs) | fs <- home_pkg_deps]
+
+    let include_paths_global = foldr (\ x xs -> ("-I" ++ x) : xs) []
+          (includePathsGlobal cmdline_include_paths ++ pkg_include_dirs
+                                                    ++ concatMap includePathsGlobal dep_pkg_extra_inputs)
+    let include_paths_quote = foldr (\ x xs -> ("-iquote" ++ x) : xs) []
+          (includePathsQuote cmdline_include_paths ++
+           includePathsQuoteImplicit cmdline_include_paths)
+    let include_paths = include_paths_quote ++ include_paths_global
+
+    let verbFlags = getVerbFlags dflags
+
+    let cpp_prog args
+          | cppUseCc opts = GHC.SysTools.runCc Nothing logger tmpfs dflags
+                                               (GHC.SysTools.Option "-E" : args)
+          | otherwise     = GHC.SysTools.runCpp logger dflags args
+
+    let platform   = targetPlatform dflags
+        targetArch = stringEncodeArch $ platformArch platform
+        targetOS = stringEncodeOS $ platformOS platform
+        isWindows = platformOS platform == OSMinGW32
+    let target_defs =
+          [ "-D" ++ HOST_OS     ++ "_BUILD_OS",
+            "-D" ++ HOST_ARCH   ++ "_BUILD_ARCH",
+            "-D" ++ targetOS    ++ "_HOST_OS",
+            "-D" ++ targetArch  ++ "_HOST_ARCH" ]
+        -- remember, in code we *compile*, the HOST is the same our TARGET,
+        -- and BUILD is the same as our HOST.
+
+    let io_manager_defs =
+          [ "-D__IO_MANAGER_WINIO__=1" | isWindows ] ++
+          [ "-D__IO_MANAGER_MIO__=1"               ]
+
+    let sse_defs =
+          [ "-D__SSE__"      | isSseEnabled      platform ] ++
+          [ "-D__SSE2__"     | isSse2Enabled     platform ] ++
+          [ "-D__SSE4_2__"   | isSse4_2Enabled   dflags ]
+
+    let avx_defs =
+          [ "-D__AVX__"      | isAvxEnabled      dflags ] ++
+          [ "-D__AVX2__"     | isAvx2Enabled     dflags ] ++
+          [ "-D__AVX512CD__" | isAvx512cdEnabled dflags ] ++
+          [ "-D__AVX512ER__" | isAvx512erEnabled dflags ] ++
+          [ "-D__AVX512F__"  | isAvx512fEnabled  dflags ] ++
+          [ "-D__AVX512PF__" | isAvx512pfEnabled dflags ]
+
+    backend_defs <- applyCDefs (backendCDefs $ backend dflags) logger dflags
+
+    let th_defs = [ "-D__GLASGOW_HASKELL_TH__" ]
+    -- Default CPP defines in Haskell source
+    ghcVersionH <- getGhcVersionPathName dflags unit_env
+    let hsSourceCppOpts = [ "-include", ghcVersionH ]
+
+    -- MIN_VERSION macros
+    let uids = explicitUnits unit_state
+        pkgs = mapMaybe (lookupUnit unit_state . fst) uids
+    mb_macro_include <-
+        if not (null pkgs) && gopt Opt_VersionMacros dflags
+            then do macro_stub <- newTempName logger tmpfs (tmpDir dflags) TFL_CurrentModule "h"
+                    writeFile macro_stub (generatePackageVersionMacros pkgs)
+                    -- Include version macros for every *exposed* package.
+                    -- Without -hide-all-packages and with a package database
+                    -- size of 1000 packages, it takes cpp an estimated 2
+                    -- milliseconds to process this file. See #10970
+                    -- comment 8.
+                    return [GHC.SysTools.FileOption "-include" macro_stub]
+            else return []
+
+    let line_pragmas
+          | cppLinePragmas opts = [] -- on by default
+          | otherwise           = [GHC.SysTools.Option "-P"] -- disable LINE markers
+
+    cpp_prog       (   map GHC.SysTools.Option verbFlags
+                    ++ map GHC.SysTools.Option include_paths
+                    ++ map GHC.SysTools.Option hsSourceCppOpts
+                    ++ map GHC.SysTools.Option target_defs
+                    ++ map GHC.SysTools.Option backend_defs
+                    ++ map GHC.SysTools.Option th_defs
+                    ++ map GHC.SysTools.Option hscpp_opts
+                    ++ map GHC.SysTools.Option sse_defs
+                    ++ map GHC.SysTools.Option avx_defs
+                    ++ map GHC.SysTools.Option io_manager_defs
+                    ++ mb_macro_include
+                    ++ extra_opts
+                    ++ line_pragmas
+        -- Set the language mode to assembler-with-cpp when preprocessing. This
+        -- alleviates some of the C99 macro rules relating to whitespace and the hash
+        -- operator, which we tend to abuse. Clang in particular is not very happy
+        -- about this.
+                    ++ [ GHC.SysTools.Option     "-x"
+                       , GHC.SysTools.Option     "assembler-with-cpp"
+                       , GHC.SysTools.Option     input_fn
+        -- We hackily use Option instead of FileOption here, so that the file
+        -- name is not back-slashed on Windows.  cpp is capable of
+        -- dealing with / in filenames, so it works fine.  Furthermore
+        -- if we put in backslashes, cpp outputs #line directives
+        -- with *double* backslashes.   And that in turn means that
+        -- our error messages get double backslashes in them.
+        -- In due course we should arrange that the lexer deals
+        -- with these \\ escapes properly.
+                       , GHC.SysTools.Option     "-o"
+                       , GHC.SysTools.FileOption "" output_fn
+                       ])
+
+-- ---------------------------------------------------------------------------
+-- Macros (cribbed from Cabal)
+
+generatePackageVersionMacros :: [UnitInfo] -> String
+generatePackageVersionMacros pkgs = concat
+  -- Do not add any C-style comments. See #3389.
+  [ generateMacros "" pkgname version
+  | pkg <- pkgs
+  , let version = unitPackageVersion pkg
+        pkgname = map fixchar (unitPackageNameString pkg)
+  ]
+
+fixchar :: Char -> Char
+fixchar '-' = '_'
+fixchar c   = c
+
+generateMacros :: String -> String -> Version -> String
+generateMacros prefix name version =
+  concat
+  ["#define ", prefix, "VERSION_",name," ",show (showVersion version),"\n"
+  ,"#define MIN_", prefix, "VERSION_",name,"(major1,major2,minor) (\\\n"
+  ,"  (major1) <  ",major1," || \\\n"
+  ,"  (major1) == ",major1," && (major2) <  ",major2," || \\\n"
+  ,"  (major1) == ",major1," && (major2) == ",major2," && (minor) <= ",minor,")"
+  ,"\n\n"
+  ]
+  where
+    take3 = \case
+      (a:b:c:_) -> (a,b,c)
+      _         -> error "take3"
+    (major1,major2,minor) = take3 $ map show (versionBranch version) ++ repeat "0"
+
+
+-- | Find out path to @ghcversion.h@ file
+getGhcVersionPathName :: DynFlags -> UnitEnv -> IO FilePath
+getGhcVersionPathName dflags unit_env = do
+  candidates <- case ghcVersionFile dflags of
+    Just path -> return [path]
+    Nothing -> do
+        ps <- mayThrowUnitErr (preloadUnitsInfo' unit_env [rtsUnitId])
+        return ((</> "ghcversion.h") <$> collectIncludeDirs ps)
+
+  found <- filterM doesFileExist candidates
+  case found of
+      []    -> throwGhcExceptionIO (InstallationError
+                                    ("ghcversion.h missing; tried: "
+                                      ++ intercalate ", " candidates))
+      (x:_) -> return x
+
+applyCDefs :: DefunctionalizedCDefs -> Logger -> DynFlags -> IO [String]
+applyCDefs NoCDefs _ _ = return []
+applyCDefs LlvmCDefs logger dflags = do
+    llvmVer <- figureLlvmVersion logger dflags
+    return $ case fmap llvmVersionList llvmVer of
+               Just [m] -> [ "-D__GLASGOW_HASKELL_LLVM__=" ++ format (m,0) ]
+               Just (m:n:_) -> [ "-D__GLASGOW_HASKELL_LLVM__=" ++ format (m,n) ]
+               _ -> []
+  where
+    format (major, minor)
+      | minor >= 100 = error "backendCDefs: Unsupported minor version"
+      | otherwise = show (100 * major + minor :: Int) -- Contract is Int
+
+
+-- Note [Filepaths and Multiple Home Units]
+offsetIncludePaths :: DynFlags -> IncludeSpecs -> IncludeSpecs
+offsetIncludePaths dflags (IncludeSpecs incs quotes impl) =
+     let go = map (augmentByWorkingDirectory dflags)
+     in IncludeSpecs (go incs) (go quotes) (go impl)
+


=====================================
compiler/ghc.cabal.in
=====================================
@@ -520,7 +520,6 @@ Library
         GHC.JS.Ppr
         GHC.JS.Syntax
         GHC.JS.Transform
-        GHC.JS.Parser.Header
         GHC.Linker
         GHC.Linker.Dynamic
         GHC.Linker.ExtraObj
@@ -666,11 +665,11 @@ Library
         GHC.StgToJS.Linker.Linker
         GHC.StgToJS.Linker.Types
         GHC.StgToJS.Linker.Utils
-        GHC.StgToJS.Linker.Shims
         GHC.Stg.Unarise
         GHC.SysTools
         GHC.SysTools.Ar
         GHC.SysTools.BaseDir
+        GHC.SysTools.Cpp
         GHC.SysTools.Elf
         GHC.SysTools.Info
         GHC.SysTools.Process


=====================================
libraries/base/jsbits/base.js
=====================================
@@ -1,8 +1,6 @@
 //#OPTIONS: CPP
 #include "HsBaseConfig.h"
 
-#include <js/rts.h>
-
 // #define GHCJS_TRACE_IO 1
 
 #ifdef GHCJS_TRACE_IO


=====================================
libraries/base/jsbits/errno.js
=====================================
@@ -1,8 +1,6 @@
 //#OPTIONS: CPP
 
 #include "HsBaseConfig.h"
-#include <js/rts.h>
-
 
 #ifdef GHCJS_TRACE_ERRNO
 function h$logErrno() { h$log.apply(h$log,arguments); }
@@ -41,6 +39,7 @@ function h$setErrno(e) {
   var es = e.toString();
   var getErr = function() {
       if(es.indexOf('ENOTDIR') !== -1)      return CONST_ENOTDIR;
+      if(es.indexOf('EISDIR') !== -1)       return CONST_EISDIR;
       if(es.indexOf('ENOENT') !== -1)       return CONST_ENOENT;
       if(es.indexOf('EEXIST') !== -1)       return CONST_EEXIST;
       if(es.indexOf('ENETUNREACH') !== -1)  return CONST_EINVAL; // fixme
@@ -63,6 +62,7 @@ var h$errorStrs =  { CONST_E2BIG:   "Argument list too long"
                    , CONST_EINVAL:  "Invalid argument"
                    , CONST_EBADF:   "Bad file descriptor"
                    , CONST_ENOTDIR: "Not a directory"
+                   , CONST_EISDIR:  "Illegal operation on a directory"
                    , CONST_ENOENT:  "No such file or directory"
                    , CONST_EPERM:   "Operation not permitted"
                    , CONST_EEXIST:  "File exists"


=====================================
rts/include/js/constants.h deleted
=====================================
@@ -1,18 +0,0 @@
-#ifndef __GHCJS_CONSTANTS_H_
-#define __GHCJS_CONSTANTS_H_
-
-// values defined in Gen2.ClosureInfo
-#define CLOSURE_TYPE_FUN (1)
-#define CLOSURE_TYPE_CON (2)
-#define CLOSURE_TYPE_THUNK (0)
-#define CLOSURE_TYPE_PAP (3)
-#define CLOSURE_TYPE_BLACKHOLE (5)
-#define CLOSURE_TYPE_STACKFRAME (-1)
-
-// thread status
-#define THREAD_RUNNING (0)
-#define THREAD_BLOCKED (1)
-#define THREAD_FINISHED (16)
-#define THREAD_DIED (17)
-
-#endif


=====================================
rts/include/js/rts.h deleted
=====================================
@@ -1,196 +0,0 @@
-#ifndef __GHCJS_RTS_H_
-#define __GHCJS_RTS_H_
-
-#include "constants.h"
-
-/*
- * low-level heap object manipulation macros
- */
-
-#ifdef GHCJS_PROF
-#define MK_TUP2(x1,x2)                           (h$c2(h$ghczmprimZCGHCziTupleziPrimziZLz2cUZR_con_e,(x1),(x2),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))
-#define MK_TUP3(x1,x2,x3)                        (h$c3(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUZR_con_e,(x1),(x2),(x3),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))
-#define MK_TUP4(x1,x2,x3,x4)                     (h$c4(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))
-#define MK_TUP5(x1,x2,x3,x4,x5)                  (h$c5(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))
-#define MK_TUP6(x1,x2,x3,x4,x5,x6)               (h$c6(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))
-#define MK_TUP7(x1,x2,x3,x4,x5,x6,x7)            (h$c7(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))
-#define MK_TUP8(x1,x2,x3,x4,x5,x6,x7,x8)         (h$c8(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))
-#define MK_TUP9(x1,x2,x3,x4,x5,x6,x7,x8,x9)      (h$c9(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),(x9),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))
-#define MK_TUP10(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10) (h$c10(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),(x9),(x10),h$currentThread?h$currentThread.ccs:h$CCS_SYSTEM))
-#else
-#define MK_TUP2(x1,x2)                           (h$c2(h$ghczmprimZCGHCziTupleziPrimziZLz2cUZR_con_e,(x1),(x2)))
-#define MK_TUP3(x1,x2,x3)                        (h$c3(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUZR_con_e,(x1),(x2),(x3)))
-#define MK_TUP4(x1,x2,x3,x4)                     (h$c4(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4)))
-#define MK_TUP5(x1,x2,x3,x4,x5)                  (h$c5(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5)))
-#define MK_TUP6(x1,x2,x3,x4,x5,x6)               (h$c6(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6)))
-#define MK_TUP7(x1,x2,x3,x4,x5,x6,x7)            (h$c7(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7)))
-#define MK_TUP8(x1,x2,x3,x4,x5,x6,x7,x8)         (h$c8(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8)))
-#define MK_TUP9(x1,x2,x3,x4,x5,x6,x7,x8,x9)      (h$c9(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),(x9)))
-#define MK_TUP10(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10) (h$c10(h$ghczmprimZCGHCziTupleziPrimziZLz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUz2cUZR_con_e,(x1),(x2),(x3),(x4),(x5),(x6),(x7),(x8),(x9),(x10)))
-#endif
-
-#define TUP2_1(x) ((x).d1)
-#define TUP2_2(x) ((x).d2)
-
-
-
-// GHC.JS.Prim.JSVal
-#ifdef GHCJS_PROF
-#define MK_JSVAL(x) (h$c1(h$baseZCGHCziJSziPrimziJSVal_con_e, (x), h$CCS_SYSTEM))
-#else
-#define MK_JSVAL(x) (h$c1(h$baseZCGHCziJSziPrimziJSVal_con_e, (x)))
-#endif
-#define JSVAL_VAL(x) ((x).d1)
-
-// GHC.JS.Prim.JSException
-#ifdef GHCJS_PROF
-#define MK_JSEXCEPTION(msg,hsMsg) (h$c2(h$baseZCGHCziJSziPrimziJSException_con_e,(msg),(hsMsg),h$CCS_SYSTEM))
-#else
-#define MK_JSEXCEPTION(msg,hsMsg) (h$c2(h$baseZCGHCziJSziPrimziJSException_con_e,(msg),(hsMsg)))
-#endif
-// Exception dictionary for JSException
-#define HS_JSEXCEPTION_EXCEPTION h$baseZCGHCziJSziPrimzizdfExceptionJSException
-
-// SomeException
-#ifdef GHCJS_PROF
-#define MK_SOMEEXCEPTION(dict,except) (h$c2(h$baseZCGHCziExceptionziTypeziSomeException_con_e,(dict),(except),h$CCS_SYSTEM))
-#else
-#define MK_SOMEEXCEPTION(dict,except) (h$c2(h$baseZCGHCziExceptionziTypeziSomeException_con_e,(dict),(except)))
-#endif
-
-// GHC.Ptr.Ptr
-#ifdef GHCJS_PROF
-#define MK_PTR(val,offset) (h$c2(h$baseZCGHCziPtrziPtr_con_e, (val), (offset), h$CCS_SYSTEM))
-#else
-#define MK_PTR(val,offset) (h$c2(h$baseZCGHCziPtrziPtr_con_e, (val), (offset)))
-#endif
-
-// GHC.Integer.GMP.Internals
-#define IS_INTEGER_S(cl) ((cl).f === h$integerzmwiredzminZCGHCziIntegerziTypeziSzh_con_e)
-#define IS_INTEGER_Jp(cl) ((cl).f === h$integerzmwiredzminZCGHCziIntegerziTypeziJpzh_con_e)
-#define IS_INTEGER_Jn(cl) ((cl).f === h$integerzmwiredzminZCGHCziIntegerziTypeziJnzh_con_e)
-#define INTEGER_S_DATA(cl) ((cl).d1)
-#define INTEGER_J_DATA(cl) ((cl).d1)
-#ifdef GHCJS_PROF
-#define MK_INTEGER_S(iii) (h$c1(h$integerzmwiredzminZCGHCziIntegerziTypeziSzh_con_e, (iii), h$CCS_SYSTEM));
-#define MK_INTEGER_Jp(iii) (h$c1(h$integerzmwiredzminZCGHCziIntegerziTypeziJpzh_con_e, (iii), h$CCS_SYSTEM));
-#define MK_INTEGER_Jn(iii) (h$c1(h$integerzmwiredzminZCGHCziIntegerziTypeziJnzh_con_e, (iii), h$CCS_SYSTEM));
-#else
-#define MK_INTEGER_S(iii) (h$c1(h$integerzmwiredzminZCGHCziIntegerziTypeziSzh_con_e, (iii)));
-#define MK_INTEGER_Jp(iii) (h$c1(h$integerzmwiredzminZCGHCziIntegerziTypeziJpzh_con_e, (iii)));
-#define MK_INTEGER_Jn(iii) (h$c1(h$integerzmwiredzminZCGHCziIntegerziTypeziJnzh_con_e, (iii)));
-#endif
-
-// Data.Maybe.Maybe
-#define HS_NOTHING h$baseZCGHCziMaybeziNothing
-#define IS_NOTHING(cl) ((cl).f === h$baseZCGHCziMaybeziNothing_con_e)
-#define IS_JUST(cl) ((cl).f === h$baseZCGHCziMaybeziJust_con_e)
-#define JUST_VAL(jj) ((jj).d1)
-// #define HS_NOTHING h$nothing
-#ifdef GHCJS_PROF
-#define MK_JUST(val) (h$c1(h$baseZCGHCziMaybeziJust_con_e, (val), h$CCS_SYSTEM))
-#else
-#define MK_JUST(val) (h$c1(h$baseZCGHCziMaybeziJust_con_e, (val)))
-#endif
-
-// Data.List
-#define HS_NIL h$ghczmprimZCGHCziTypesziZMZN
-#define HS_NIL_CON h$ghczmprimZCGHCziTypesziZMZN_con_e
-#define IS_CONS(cl) ((cl).f === h$ghczmprimZCGHCziTypesziZC_con_e)
-#define IS_NIL(cl) ((cl).f === h$ghczmprimZCGHCziTypesziZMZN_con_e)
-#define CONS_HEAD(cl) ((cl).d1)
-#define CONS_TAIL(cl) ((cl).d2)
-#ifdef GHCJS_PROF
-#define MK_CONS(head,tail) (h$c2(h$ghczmprimZCGHCziTypesziZC_con_e, (head), (tail), h$CCS_SYSTEM))
-#define MK_CONS_CC(head,tail,cc) (h$c2(h$ghczmprimZCGHCziTypesziZC_con_e, (head), (tail), (cc)))
-#else
-#define MK_CONS(head,tail) (h$c2(h$ghczmprimZCGHCziTypesziZC_con_e, (head), (tail)))
-#define MK_CONS_CC(head,tail,cc) (h$c2(h$ghczmprimZCGHCziTypesziZC_con_e, (head), (tail)))
-#endif
-
-// Data.Text
-#define DATA_TEXT_ARRAY(x) ((x).d1)
-#define DATA_TEXT_OFFSET(x) ((x).d2.d1)
-#define DATA_TEXT_LENGTH(x) ((x).d2.d2)
-
-// Data.Text.Lazy
-#define LAZY_TEXT_IS_CHUNK(x) ((x).f.a === 2)
-#define LAZY_TEXT_IS_NIL(x) ((x).f.a === 1)
-#define LAZY_TEXT_CHUNK_HEAD(x) ((x))
-#define LAZY_TEXT_CHUNK_TAIL(x) ((x).d2.d3)
-
-// black holes
-// can we skip the indirection for black holes?
-#define IS_BLACKHOLE(x) (typeof (x) === 'object' && (x) && (x).f && (x).f.t === CLOSURE_TYPE_BLACKHOLE)
-#define BLACKHOLE_TID(bh) ((bh).d1)
-#define SET_BLACKHOLE_TID(bh,tid) ((bh).d1 = (tid))
-#define BLACKHOLE_QUEUE(bh) ((bh).d2)
-#define SET_BLACKHOLE_QUEUE(bh,val) ((bh).d2 = (val))
-
-// resumable thunks
-#define MAKE_RESUMABLE(closure,stack) { (closure).f = h$resume_e; (closure).d1 = (stack), (closure).d2 = null; }
-
-// general deconstruction
-#define IS_THUNK(x) ((x).f.t === CLOSURE_TYPE_THUNK)
-#define CONSTR_TAG(x) ((x).f.a)
-
-// retrieve  a numeric value that's possibly stored as an indirection
-#define IS_WRAPPED_NUMBER(val) ((typeof(val)==='object')&&(val).f === h$unbox_e)
-#define UNWRAP_NUMBER(val) ((typeof(val) === 'number')?(val):(val).d1)
-
-// generic lazy values
-#ifdef GHCJS_PROF
-#define MK_LAZY(fun) (h$c1(h$lazy_e, (fun), h$CCS_SYSTEM))
-#define MK_LAZY_CC(fun,cc) (h$c1(h$lazy_e, (fun), (cc)))
-#else
-#define MK_LAZY(fun) (h$c1(h$lazy_e, (fun)))
-#define MK_LAZY_CC(fun,cc) (h$c1(h$lazy_e, (fun)))
-#endif
-
-// generic data constructors and selectors
-#ifdef GHCJS_PROF
-#define MK_DATA1_1(val) (h$c1(h$data1_e, (val), h$CCS_SYSTEM))
-#define MK_DATA1_2(val1,val2) (h$c2(h$data1_e, (val1), (val2), h$CCS_SYSTEM))
-#define MK_DATA2_1(val) (h$c1(h$data2_e, (val), h$CCS_SYSTEM))
-#define MK_DATA2_2(val1,val2) (h$c2(h$data1_e, (val1), (val2), h$CCS_SYSTEM))
-#define MK_SELECT1(val) (h$c1(h$select1_e, (val), h$CCS_SYSTEM))
-#define MK_SELECT2(val) (h$c1(h$select2_e, (val), h$CCS_SYSTEM))
-#define MK_AP1(fun,val) (h$c2(h$ap1_e, (fun), (val), h$CCS_SYSTEM))
-#define MK_AP2(fun,val1,val2) (h$c3(h$ap2_e, (fun), (val1), (val2), h$CCS_SYSTEM))
-#define MK_AP3(fun,val1,val2,val3) (h$c4(h$ap3_e, (fun), (val1), (val2), (val3), h$CCS_SYSTEM))
-#else
-#define MK_DATA1_1(val) (h$c1(h$data1_e, (val)))
-#define MK_DATA1_2(val1,val2) (h$c2(h$data1_e, (val1), (val2)))
-#define MK_DATA2_1(val) (h$c1(h$data2_e, (val)))
-#define MK_DATA2_2(val1,val2) (h$c2(h$data2_e, (val1), (val2)))
-#define MK_SELECT1(val) (h$c1(h$select1_e, (val)))
-#define MK_SELECT2(val) (h$c1(h$select2_e, (val)))
-#define MK_AP1(fun,val) (h$c2(h$ap1_e,(fun),(val)))
-#define MK_AP2(fun,val1,val2) (h$c3(h$ap2_e,(fun),(val1),(val2)))
-#define MK_AP3(fun,val1,val2,val3) (h$c4(h$ap3_e, (fun), (val1), (val2), (val3)))
-#endif
-
-// unboxed tuple returns
-// #define RETURN_UBX_TUP1(x) return x;
-#define RETURN_UBX_TUP2(x1,x2) { h$ret1 = (x2); return (x1); }
-#define RETURN_UBX_TUP3(x1,x2,x3) { h$ret1 = (x2); h$ret2 = (x3); return (x1); }
-#define RETURN_UBX_TUP4(x1,x2,x3,x4) { h$ret1 = (x2); h$ret2 = (x3); h$ret3 = (x4); return (x1); }
-#define RETURN_UBX_TUP5(x1,x2,x3,x4,x5) { h$ret1 = (x2); h$ret2 = (x3); h$ret3 = (x4); h$ret4 = (x5); return (x1); }
-#define RETURN_UBX_TUP6(x1,x2,x3,x4,x5,x6) { h$ret1 = (x2); h$ret2 = (x3); h$ret3 = (x4); h$ret4 = (x5); h$ret5 = (x6); return (x1); }
-#define RETURN_UBX_TUP7(x1,x2,x3,x4,x5,x6,x7) { h$ret1 = (x2); h$ret2 = (x3); h$ret3 = (x4); h$ret4 = (x5); h$ret5 = (x6); h$ret6 = (x7); return (x1); }
-#define RETURN_UBX_TUP8(x1,x2,x3,x4,x5,x6,x7,x8) { h$ret1 = (x2); h$ret2 = (x3); h$ret3 = (x4); h$ret4 = (x5); h$ret5 = (x6); h$ret6 = (x7); h$ret7 = (x8); return (x1); }
-#define RETURN_UBX_TUP9(x1,x2,x3,x4,x5,x6,x7,x8,x9) { h$ret1 = (x2); h$ret2 = (x3); h$ret3 = (x4); h$ret4 = (x5); h$ret5 = (x6); h$ret6 = (x7); h$ret7 = (x8); h$ret8 = (x9); return (x1); }
-#define RETURN_UBX_TUP10(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10) { h$ret1 = (x2); h$ret2 = (x3); h$ret3 = (x4); h$ret4 = (x5); h$ret5 = (x6); h$ret6 = (x7); h$ret7 = (x8); h$ret8 = (x9); h$ret9 = (x10); return (x1); }
-
-#define CALL_UBX_TUP2(r1,r2,c) { (r1) = (c); (r2) = h$ret1; }
-#define CALL_UBX_TUP3(r1,r2,r3,c) { (r1) = (c); (r2) = h$ret1; (r3) = h$ret2; }
-#define CALL_UBX_TUP4(r1,r2,r3,r4,c) { (r1) = (c); (r2) = h$ret1; (r3) = h$ret2; (r4) = h$ret3; }
-#define CALL_UBX_TUP5(r1,r2,r3,r4,r5,c) { (r1) = (c); (r2) = h$ret1; (r3) = h$ret2; (r4) = h$ret3; (r5) = h$ret4; }
-#define CALL_UBX_TUP6(r1,r2,r3,r4,r5,r6,c) { (r1) = (c); (r2) = h$ret1; (r3) = h$ret2; (r4) = h$ret3; (r5) = h$ret4; (r6) = h$ret5; }
-#define CALL_UBX_TUP7(r1,r2,r3,r4,r5,r6,r7,c) { (r1) = (c); (r2) = h$ret1; (r3) = h$ret2; (r4) = h$ret3; (r5) = h$ret4; (r6) = h$ret5; (r7) = h$ret6; }
-#define CALL_UBX_TUP8(r1,r2,r3,r4,r5,r6,r7,r8,c) { (r1) = (c); (r2) = h$ret1; (r3) = h$ret2; (r4) = h$ret3; (r5) = h$ret4; (r6) = h$ret5; (r7) = h$ret6; (r8) = h$ret7; }
-#define CALL_UBX_TUP9(r1,r2,r3,r4,r5,r6,r7,r8,r9,c) { (r1) = (c); (r2) = h$ret1; (r3) = h$ret2; (r4) = h$ret3; (r5) = h$ret4; (r6) = h$ret5; (r7) = h$ret6; (r8) = h$ret7; (r9) = h$ret8; }
-#define CALL_UBX_TUP10(r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,c) { (r1) = (c); (r2) = h$ret1; (r3) = h$ret2; (r4) = h$ret3; (r5) = h$ret4; (r6) = h$ret5; (r7) = h$ret6; (r8) = h$ret7; (r9) = h$ret8; (r10) = h$ret9; }
-
-
-#endif


=====================================
rts/js/arith.js
=====================================
@@ -1,8 +1,6 @@
 //#OPTIONS: CPP
 // #define GHCJS_TRACE_ARITH 1
 
-#include <js/rts.h>
-
 #ifdef GHCJS_TRACE_ARITH
 function h$logArith() { h$log.apply(h$log,arguments); }
 #define TRACE_ARITH(args...) h$logArith(args)


=====================================
rts/js/compact.js
=====================================
@@ -1,7 +1,5 @@
 //#OPTIONS: CPP
 
-#include <js/rts.h>
-
 #ifdef GHCJS_TRACE_COMPACT
 function h$logCompact() { h$log.apply(h$log,arguments); }
 #define TRACE_COMPACT(args...) h$logCompact(args)


=====================================
rts/js/environment.js
=====================================
@@ -1,7 +1,5 @@
 //#OPTIONS: CPP
 
-#include <js/rts.h>
-
 #ifdef GHCJS_TRACE_ENV
 function h$logEnv() { h$log.apply(h$log,arguments); }
 #define TRACE_ENV(args...) h$logEnv(args)


=====================================
rts/js/globals.js
=====================================
@@ -0,0 +1,19 @@
+//#OPTIONS: CPP
+
+// Globals used by GHC
+
+#define GVAR(name,nvar) \
+  var h$global_ ## nvar ## _a = null;\
+  var h$global_ ## nvar ## _o = null;\
+  function name(a,o) {\
+    if (!h$global_ ## nvar ## _a) {\
+      h$global_ ## nvar ## _a = a;\
+      h$global_ ## nvar ## _o = o;\
+    }\
+    RETURN_UBX_TUP2(h$global_ ## nvar ##_a, h$global_ ## nvar ##_o);\
+  }
+
+GVAR(h$getOrSetLibHSghcGlobalHasPprDebug, has_ppr_debug)
+GVAR(h$getOrSetLibHSghcGlobalHasNoDebugOutput, has_no_debug_output)
+GVAR(h$getOrSetLibHSghcGlobalHasNoStateHack, has_no_state_hack)
+GVAR(h$getOrSetLibHSghcFastStringTable, faststring_table)


=====================================
rts/js/hscore.js
=====================================
@@ -1,7 +1,5 @@
 //#OPTIONS: CPP
 
-#include <js/rts.h>
-
 #ifdef GHCJS_TRACE_HSCORE
 function h$logHscore() { h$log.apply(h$log,arguments); }
 #define TRACE_HSCORE(args...) h$logHscore(args)


=====================================
rts/js/mem.js
=====================================
@@ -1,7 +1,5 @@
 //#OPTIONS: CPP
 
-#include <js/rts.h>
-
 // #define GHCJS_TRACE_META 1
 
 #ifdef GHCJS_TRACE_META


=====================================
rts/js/object.js
=====================================
@@ -1,7 +1,5 @@
 //#OPTIONS: CPP
 
-#include <js/rts.h>
-
 // JS Objects stuff
 
 function h$isFloat (n) {


=====================================
rts/js/rts.js
=====================================
@@ -1,7 +1,5 @@
 //#OPTIONS: CPP
 
-#include <js/rts.h>
-
 var h$start = new Date();
 
 function h$rts_eval(action, unbox) {


=====================================
rts/js/staticpointer.js
=====================================
@@ -1,7 +1,5 @@
 //#OPTIONS: CPP
 
-#include <js/rts.h>
-
 // static pointers
 var h$static_pointer_table      = null;
 var h$static_pointer_table_keys = null;


=====================================
rts/js/string.js
=====================================
@@ -1,7 +1,5 @@
 //#OPTIONS: CPP
 
-#include <js/rts.h>
-
 // encode a string constant
 function h$str(s) {
   var enc = null;


=====================================
rts/js/thread.js
=====================================
@@ -1,7 +1,5 @@
 //#OPTIONS: CPP
 
-#include <js/rts.h>
-
 // preemptive threading support
 
 // run gc when this much time has passed (ms)


=====================================
rts/js/weak.js
=====================================
@@ -1,7 +1,5 @@
 //#OPTIONS: CPP
 
-#include <js/rts.h>
-
 // weak reference support
 
 var h$weakPointerList = [];


=====================================
rts/rts.cabal.in
=====================================
@@ -84,6 +84,7 @@ library
         js/enum.js
         js/environment.js
         js/gc.js
+        js/globals.js
         js/goog.js
         js/hscore.js
         js/md5.js
@@ -107,8 +108,6 @@ library
                         stg/MachRegs.h
                         stg/MachRegsForHost.h
                         stg/Types.h
-                        js/rts.h
-                        js/constants.h
 
     else
       -- If we are using an in-tree libffi then we must declare it as a bundled



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1ec975cac75be10ac77b472550d7df4dabdb2da4...0015d2d96866b09142cf58fcc27ef4ffbfcda9bc

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1ec975cac75be10ac77b472550d7df4dabdb2da4...0015d2d96866b09142cf58fcc27ef4ffbfcda9bc
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20221011/9bd92d7f/attachment-0001.html>


More information about the ghc-commits mailing list