Skip to content

Commit c1a8289

Browse files
authored
Lua: fix global module loading (#7701)
1 parent 2b23861 commit c1a8289

File tree

1 file changed

+27
-7
lines changed

1 file changed

+27
-7
lines changed

src/Text/Pandoc/Lua/Init.hs

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@ module Text.Pandoc.Lua.Init
1414
( runLua
1515
) where
1616

17-
import Control.Monad (forM_, when)
17+
import Control.Monad (forM, forM_, when)
1818
import Control.Monad.Catch (throwM, try)
1919
import Control.Monad.Trans (MonadIO (..))
2020
import Data.Data (Data, dataTypeConstrs, dataTypeOf, showConstr)
21+
import Data.Maybe (catMaybes)
2122
import HsLua as Lua hiding (status, try)
2223
import GHC.IO.Encoding (getForeignEncoding, setForeignEncoding, utf8)
2324
import Text.Pandoc.Class.PandocMonad (PandocMonad, readDataFile)
@@ -78,23 +79,42 @@ initLuaState = do
7879
_ -> T.pack $ show err
7980

8081
setGlobalModules :: PandocLua ()
81-
setGlobalModules = liftPandocLua $
82-
forM_ [ ("lpeg", LPeg.luaopen_lpeg_ptr)
83-
, ("re", LPeg.luaopen_re_ptr)
84-
] $
82+
setGlobalModules = liftPandocLua $ do
83+
let globalModules =
84+
[ ("lpeg", LPeg.luaopen_lpeg_ptr) -- must be loaded first
85+
, ("re", LPeg.luaopen_re_ptr) -- re depends on lpeg
86+
]
87+
loadedBuiltInModules <- fmap catMaybes . forM globalModules $
8588
\(pkgname, luaopen) -> do
8689
Lua.pushcfunction luaopen
87-
Lua.pcall 0 1 Nothing >>= \case
88-
OK -> pure () -- all good, loading succeeded
90+
usedBuiltIn <- Lua.pcall 0 1 Nothing >>= \case
91+
OK -> do -- all good, loading succeeded
92+
-- register as loaded module so later modules can rely on this
93+
Lua.getfield Lua.registryindex Lua.loaded
94+
Lua.pushvalue (Lua.nth 2)
95+
Lua.setfield (Lua.nth 2) pkgname
96+
Lua.pop 1 -- pop _LOADED
97+
return True
8998
_ -> do -- built-in library failed, load system lib
9099
Lua.pop 1 -- ignore error message
91100
-- Try loading via the normal package loading mechanism.
92101
Lua.getglobal "require"
93102
Lua.pushName pkgname
94103
Lua.call 1 1 -- Throws an exception if loading failed again!
104+
return False
95105

96106
-- Module on top of stack. Register as global
97107
Lua.setglobal pkgname
108+
return $ if usedBuiltIn then Just pkgname else Nothing
109+
110+
-- Remove module entry from _LOADED table in registry if we used a
111+
-- built-in library. This ensures that later calls to @require@ will
112+
-- prefer the shared library, if any.
113+
forM_ loadedBuiltInModules $ \pkgname -> do
114+
Lua.getfield Lua.registryindex Lua.loaded
115+
Lua.pushnil
116+
Lua.setfield (Lua.nth 2) pkgname
117+
Lua.pop 1 -- registry
98118

99119
installLpegSearcher :: PandocLua ()
100120
installLpegSearcher = liftPandocLua $ do

0 commit comments

Comments
 (0)