@@ -29,7 +29,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29Lua utility functions.
29Lua utility functions.
31module Text.Pandoc.Lua.Util
31module Text.Pandoc.Lua.Util
32− ( adjustIndexBy
32+ ( getTag
33 , getTable
33 , getTable
34 , addValue
34 , addValue
35 , addFunction
35 , addFunction
@@ -47,6 +47,7 @@ module Text.Pandoc.Lua.Util
49import Control.Monad (when)
49import Control.Monad (when)
50+import Control.Monad.Catch (finally)
50import Data.ByteString.Char8 (unpack)
51import Data.ByteString.Char8 (unpack)
51import Foreign.Lua (FromLuaStack (..), NumResults, Lua, NumArgs, StackIndex,
52import Foreign.Lua (FromLuaStack (..), NumResults, Lua, NumArgs, StackIndex,
52 ToLuaStack (..), ToHaskellFunction, getglobal')
53 ToLuaStack (..), ToHaskellFunction, getglobal')
@@ -163,11 +164,23 @@ loadScriptFromDataDir datadir scriptFile = do
163-- to @require@, the a new loader function was created which then become
164-- to @require@, the a new loader function was created which then become
164-- garbage. If that function is collected at an inopportune times, i.e. when the
165-- garbage. If that function is collected at an inopportune times, i.e. when the
165-- Lua API is called via a function that doesn't allow calling back into Haskell
166-- Lua API is called via a function that doesn't allow calling back into Haskell
166−-- (getraw, setraw, …). The function's finalizer, and the full program, hangs
167+-- (getraw, setraw, …), then the function's finalizer, and the full program,
167−-- when that happens.
168+-- will hang.
168dostring' :: String -> Lua Status
169dostring' :: String -> Lua Status
169dostring' script = do
170dostring' script = do
170 loadRes <- Lua.loadstring script
171 loadRes <- Lua.loadstring script
171 if loadRes == Lua.OK
172 if loadRes == Lua.OK
172 then Lua.pcall 0 1 Nothing <* Lua.gc Lua.GCCOLLECT 0
173 then Lua.pcall 0 1 Nothing <* Lua.gc Lua.GCCOLLECT 0
173 else return loadRes
174 else return loadRes
176+-- | Get the tag of a value. This is an optimized and specialized version of
177+-- @Lua.getfield idx "tag"@. It only checks for the field on the table at index
178+-- @idx@ and on its metatable, also ignoring any @__index@ value on the
180+getTag :: StackIndex -> Lua String
183+ hasMT <- Lua.getmetatable idx
185+ if hasMT then Lua.rawget (-2) else Lua.rawget (idx `adjustIndexBy` 1)
186+ peek Lua.stackTop `finally` Lua.settop top