Visitar URL original
How to make HsLua.error called from lua_sethook work? · Issue #125 · hslua/hslua · GitHub
Skip to content

How to make HsLua.error called from lua_sethook work? #125

Open

Description

@iammemir

I want to limit maximum count of executed instructions with lua_sethook. I wrote some very naive wrapper for it and call HsLua.error from callback, but seems that Lua just ignored the error and execution continued. What should I do?
My example code below. Thanks.

{-# LANGUAGE OverloadedStrings #-}

module Main where

import           Control.Monad
import           Control.Monad.IO.Class
import           Data.ByteString        (ByteString)
import           Data.String
import           Foreign.Ptr
import           GHC.IO.Unsafe

import qualified HsLua

foreign import ccall "wrapper"
  wrap
    :: (HsLua.State -> Ptr () -> ())
    -> IO (FunPtr (HsLua.State -> Ptr () -> ()))

foreign import ccall "lua.h" lua_sethook
    :: HsLua.State -- ^ Lua State
    -> FunPtr (HsLua.State -> Ptr () -> ()) -- ^ Hook callback
    -> HsLua.Integer -- ^ Mask
    -> HsLua.Integer -- ^ Limit
    -> IO HsLua.Integer

everyNthInstruction
    :: HsLua.Integer
    -> HsLua.LuaE e ()
    -> HsLua.LuaE e HsLua.Integer
everyNthInstruction limit m = do st <- HsLua.state
                                 liftIO $ do
                                    cb <- wrap $ \s _ -> unsafePerformIO
                                        $ HsLua.runWith s m
                                    lua_sethook st cb
                                        8 -- LUA_MASKCOUNT
                                        limit

limit :: HsLua.LuaE HsLua.Exception ()
limit = void $ everyNthInstruction 100 $ do liftIO $ putStrLn "Call!"
                                            HsLua.pushString "Limit exceeded"
                                            void HsLua.error

runCode :: ByteString -> IO (Either HsLua.Exception ByteString)
runCode source = HsLua.runEither $ do limit
                                      HsLua.openbase
                                      HsLua.dostring source
                                      HsLua.tostring' (-1)

main :: IO ()
main = runCode (fromString "while(true) do print('a') end") >>= print

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions