{-# Language ForeignFunctionInterface #-}
module EVM.Precompiled (execute) where
import Data.ByteString (ByteString)
import qualified Data.ByteString as BS
import Foreign.C
import Foreign.Ptr
import Foreign.ForeignPtr
import System.IO.Unsafe
data EthjetContext
foreign import ccall "ethjet_init"
  ethjet_init :: IO (Ptr EthjetContext)
foreign import ccall "ðjet_free"
  ethjet_free :: FunPtr (Ptr EthjetContext -> IO ())
foreign import ccall "ethjet"
  ethjet
    :: Ptr EthjetContext     
    -> CInt                  
    -> Ptr CChar -> CInt     
    -> Ptr CChar -> CInt     
    -> IO CInt               
globalContext :: ForeignPtr EthjetContext
{-# NOINLINE globalContext #-}
globalContext =
  unsafePerformIO $
    ethjet_init >>= newForeignPtr ethjet_free
execute
  :: Int                
  -> ByteString         
  -> Int                
  -> Maybe ByteString   
execute contract input outputSize =
  
  
  
  
  unsafePerformIO . BS.useAsCStringLen input $
    \(inputPtr, inputSize) -> do
       outputForeignPtr <- mallocForeignPtrBytes outputSize
       withForeignPtr outputForeignPtr $ \outputPtr -> do
         status <-
           withForeignPtr globalContext $ \contextPtr ->
             
             ethjet contextPtr (fromIntegral contract)
               inputPtr (fromIntegral inputSize)
               outputPtr (fromIntegral outputSize)
         case status of
           1 -> Just <$> BS.packCStringLen (outputPtr, outputSize)
           _ -> pure Nothing