{-# Language ImplicitParams #-}
{-# Language TemplateHaskell #-}
{-# Language DataKinds #-}
{-# Language FlexibleInstances #-}
module EVM.Emacs where
import Control.Lens
import Control.Monad.IO.Class
import Control.Monad.State.Strict hiding (state)
import Data.ByteString (ByteString)
import Data.Map (Map)
import Data.Maybe
import Data.Monoid
import Data.SCargot
import Data.SCargot.Language.HaskLike
import Data.SCargot.Repr
import Data.SCargot.Repr.Basic
import Data.Set (Set)
import Data.Text (Text, pack, unpack)
import Data.SBV hiding (Word, output)
import EVM
import EVM.ABI
import EVM.Symbolic
import EVM.Dapp
import EVM.Debug (srcMapCodePos)
import EVM.Fetch (Fetcher)
import EVM.Solidity
import EVM.Stepper (Stepper)
import EVM.TTY (currentSrcMap)
import EVM.Types
import EVM.UnitTest
import Prelude hiding (Word)
import System.Directory
import System.IO
import qualified Control.Monad.Operational as Operational
import qualified Data.List as List
import qualified Data.Map as Map
import qualified Data.Set as Set
import qualified EVM.Fetch as Fetch
import qualified EVM.Stepper as Stepper
data UiVmState = UiVmState
{ UiVmState -> VM
_uiVm :: VM
, UiVmState -> Stepper ()
_uiVmNextStep :: Stepper ()
, UiVmState -> Maybe SolcContract
_uiVmSolc :: Maybe SolcContract
, UiVmState -> Maybe DappInfo
_uiVmDapp :: Maybe DappInfo
, UiVmState -> Int
_uiVmStepCount :: Int
, UiVmState -> UiVmState
_uiVmFirstState :: UiVmState
, UiVmState -> Fetcher
_uiVmFetcher :: Fetcher
, UiVmState -> Maybe Text
_uiVmMessage :: Maybe Text
, UiVmState -> Set W256
_uiVmSentHashes :: Set W256
}
makeLenses ''UiVmState
type Pred a = a -> Bool
data StepMode
= StepOne
| StepMany !Int
| StepNone
| StepUntil (Pred VM)
data StepOutcome a
= Returned a
| Stepped (Stepper a)
| Blocked (IO (Stepper a))
interpret
:: StepMode
-> Stepper a
-> State UiVmState (StepOutcome a)
interpret :: StepMode -> Stepper a -> State UiVmState (StepOutcome a)
interpret StepMode
mode =
ProgramView Action a -> State UiVmState (StepOutcome a)
forall a. ProgramView Action a -> State UiVmState (StepOutcome a)
eval (ProgramView Action a -> State UiVmState (StepOutcome a))
-> (Stepper a -> ProgramView Action a)
-> Stepper a
-> State UiVmState (StepOutcome a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Stepper a -> ProgramView Action a
forall (instr :: * -> *) a. Program instr a -> ProgramView instr a
Operational.view
where
eval
:: Operational.ProgramView Stepper.Action a
-> State UiVmState (StepOutcome a)
eval :: ProgramView Action a -> State UiVmState (StepOutcome a)
eval (Operational.Return a
x) =
StepOutcome a -> State UiVmState (StepOutcome a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a -> StepOutcome a
forall a. a -> StepOutcome a
Returned a
x)
eval (Action b
action Operational.:>>= b -> ProgramT Action Identity a
k) =
case Action b
action of
Action b
Stepper.Exec -> do
let
restart :: ProgramT Action Identity a
restart = Stepper VMResult
Stepper.exec Stepper VMResult
-> (VMResult -> ProgramT Action Identity a)
-> ProgramT Action Identity a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= b -> ProgramT Action Identity a
VMResult -> ProgramT Action Identity a
k
case StepMode
mode of
StepMode
StepNone ->
StepOutcome a -> State UiVmState (StepOutcome a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ProgramT Action Identity a -> StepOutcome a
forall a. Stepper a -> StepOutcome a
Stepped (Action b -> ProgramT Action Identity b
forall (instr :: * -> *) a (m :: * -> *).
instr a -> ProgramT instr m a
Operational.singleton Action b
action ProgramT Action Identity b
-> (b -> ProgramT Action Identity a) -> ProgramT Action Identity a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= b -> ProgramT Action Identity a
k))
StepMode
StepOne -> do
(UiVmState -> UiVmState) -> StateT UiVmState Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify UiVmState -> UiVmState
stepOneOpcode
Getting (Maybe VMResult) UiVmState (Maybe VMResult)
-> StateT UiVmState Identity (Maybe VMResult)
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use ((VM -> Const (Maybe VMResult) VM)
-> UiVmState -> Const (Maybe VMResult) UiVmState
Lens' UiVmState VM
uiVm ((VM -> Const (Maybe VMResult) VM)
-> UiVmState -> Const (Maybe VMResult) UiVmState)
-> ((Maybe VMResult -> Const (Maybe VMResult) (Maybe VMResult))
-> VM -> Const (Maybe VMResult) VM)
-> Getting (Maybe VMResult) UiVmState (Maybe VMResult)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe VMResult -> Const (Maybe VMResult) (Maybe VMResult))
-> VM -> Const (Maybe VMResult) VM
Lens' VM (Maybe VMResult)
result) StateT UiVmState Identity (Maybe VMResult)
-> (Maybe VMResult -> State UiVmState (StepOutcome a))
-> State UiVmState (StepOutcome a)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Maybe VMResult
Nothing ->
StepOutcome a -> State UiVmState (StepOutcome a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ProgramT Action Identity a -> StepOutcome a
forall a. Stepper a -> StepOutcome a
Stepped ProgramT Action Identity a
restart)
Just VMResult
r ->
StepMode
-> ProgramT Action Identity a -> State UiVmState (StepOutcome a)
forall a. StepMode -> Stepper a -> State UiVmState (StepOutcome a)
interpret StepMode
StepNone (b -> ProgramT Action Identity a
k b
VMResult
r)
StepMany Int
0 ->
StepMode
-> ProgramT Action Identity a -> State UiVmState (StepOutcome a)
forall a. StepMode -> Stepper a -> State UiVmState (StepOutcome a)
interpret StepMode
StepNone ProgramT Action Identity a
restart
StepMany Int
i ->
StepMode
-> ProgramT Action Identity a -> State UiVmState (StepOutcome a)
forall a. StepMode -> Stepper a -> State UiVmState (StepOutcome a)
interpret StepMode
StepOne ProgramT Action Identity a
restart State UiVmState (StepOutcome a)
-> (StepOutcome a -> State UiVmState (StepOutcome a))
-> State UiVmState (StepOutcome a)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
\case
Stepped ProgramT Action Identity a
stepper ->
StepMode
-> ProgramT Action Identity a -> State UiVmState (StepOutcome a)
forall a. StepMode -> Stepper a -> State UiVmState (StepOutcome a)
interpret (Int -> StepMode
StepMany (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)) ProgramT Action Identity a
stepper
StepOutcome a
r -> StepOutcome a -> State UiVmState (StepOutcome a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure StepOutcome a
r
StepUntil Pred VM
p -> do
VM
vm <- Getting VM UiVmState VM -> StateT UiVmState Identity VM
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use Getting VM UiVmState VM
Lens' UiVmState VM
uiVm
case Pred VM
p VM
vm of
Bool
True ->
StepMode
-> ProgramT Action Identity a -> State UiVmState (StepOutcome a)
forall a. StepMode -> Stepper a -> State UiVmState (StepOutcome a)
interpret StepMode
StepNone ProgramT Action Identity a
restart
Bool
False ->
StepMode
-> ProgramT Action Identity a -> State UiVmState (StepOutcome a)
forall a. StepMode -> Stepper a -> State UiVmState (StepOutcome a)
interpret StepMode
StepOne ProgramT Action Identity a
restart State UiVmState (StepOutcome a)
-> (StepOutcome a -> State UiVmState (StepOutcome a))
-> State UiVmState (StepOutcome a)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
\case
Stepped ProgramT Action Identity a
stepper ->
StepMode
-> ProgramT Action Identity a -> State UiVmState (StepOutcome a)
forall a. StepMode -> Stepper a -> State UiVmState (StepOutcome a)
interpret (Pred VM -> StepMode
StepUntil Pred VM
p) ProgramT Action Identity a
stepper
StepOutcome a
r -> StepOutcome a -> State UiVmState (StepOutcome a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure StepOutcome a
r
Stepper.Wait Query
q -> do
Fetcher
fetcher <- Getting Fetcher UiVmState Fetcher
-> StateT UiVmState Identity Fetcher
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use Getting Fetcher UiVmState Fetcher
Lens' UiVmState Fetcher
uiVmFetcher
StepOutcome a -> State UiVmState (StepOutcome a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (StepOutcome a -> State UiVmState (StepOutcome a))
-> (IO (ProgramT Action Identity a) -> StepOutcome a)
-> IO (ProgramT Action Identity a)
-> State UiVmState (StepOutcome a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO (ProgramT Action Identity a) -> StepOutcome a
forall a. IO (Stepper a) -> StepOutcome a
Blocked (IO (ProgramT Action Identity a)
-> State UiVmState (StepOutcome a))
-> IO (ProgramT Action Identity a)
-> State UiVmState (StepOutcome a)
forall a b. (a -> b) -> a -> b
$ do
EVM ()
m <- Fetcher
fetcher Query
q
ProgramT Action Identity a -> IO (ProgramT Action Identity a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (EVM () -> Stepper ()
forall a. EVM a -> Stepper a
Stepper.evm EVM ()
m Stepper ()
-> ProgramT Action Identity a -> ProgramT Action Identity a
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> b -> ProgramT Action Identity a
k ())
Stepper.EVM EVM b
m -> do
VM
vm0 <- Getting VM UiVmState VM -> StateT UiVmState Identity VM
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use Getting VM UiVmState VM
Lens' UiVmState VM
uiVm
let (b
r, VM
vm1) = EVM b -> VM -> (b, VM)
forall s a. State s a -> s -> (a, s)
runState EVM b
m VM
vm0
(UiVmState -> UiVmState) -> StateT UiVmState Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((UiVmState -> VM -> UiVmState) -> VM -> UiVmState -> UiVmState
forall a b c. (a -> b -> c) -> b -> a -> c
flip UiVmState -> VM -> UiVmState
updateUiVmState VM
vm1)
(UiVmState -> UiVmState) -> StateT UiVmState Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify UiVmState -> UiVmState
updateSentHashes
StepMode
-> ProgramT Action Identity a -> State UiVmState (StepOutcome a)
forall a. StepMode -> Stepper a -> State UiVmState (StepOutcome a)
interpret StepMode
mode (b -> ProgramT Action Identity a
k b
r)
stepOneOpcode :: UiVmState -> UiVmState
stepOneOpcode :: UiVmState -> UiVmState
stepOneOpcode UiVmState
ui =
let
nextVm :: VM
nextVm = EVM () -> VM -> VM
forall s a. State s a -> s -> s
execState EVM ()
exec1 (Getting VM UiVmState VM -> UiVmState -> VM
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting VM UiVmState VM
Lens' UiVmState VM
uiVm UiVmState
ui)
in
UiVmState
ui UiVmState -> (UiVmState -> UiVmState) -> UiVmState
forall a b. a -> (a -> b) -> b
& ASetter UiVmState UiVmState Int Int
-> (Int -> Int) -> UiVmState -> UiVmState
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over ASetter UiVmState UiVmState Int Int
Lens' UiVmState Int
uiVmStepCount (Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
UiVmState -> (UiVmState -> UiVmState) -> UiVmState
forall a b. a -> (a -> b) -> b
& ASetter UiVmState UiVmState VM VM -> VM -> UiVmState -> UiVmState
forall s t a b. ASetter s t a b -> b -> s -> t
set ASetter UiVmState UiVmState VM VM
Lens' UiVmState VM
uiVm VM
nextVm
updateUiVmState :: UiVmState -> VM -> UiVmState
updateUiVmState :: UiVmState -> VM -> UiVmState
updateUiVmState UiVmState
ui VM
vm =
UiVmState
ui UiVmState -> (UiVmState -> UiVmState) -> UiVmState
forall a b. a -> (a -> b) -> b
& ASetter UiVmState UiVmState VM VM -> VM -> UiVmState -> UiVmState
forall s t a b. ASetter s t a b -> b -> s -> t
set ASetter UiVmState UiVmState VM VM
Lens' UiVmState VM
uiVm VM
vm
updateSentHashes :: UiVmState -> UiVmState
updateSentHashes :: UiVmState -> UiVmState
updateSentHashes UiVmState
ui =
let sent :: Set W256
sent = VM -> Set W256
allHashes (Getting VM UiVmState VM -> UiVmState -> VM
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting VM UiVmState VM
Lens' UiVmState VM
uiVm UiVmState
ui) in
UiVmState
ui UiVmState -> (UiVmState -> UiVmState) -> UiVmState
forall a b. a -> (a -> b) -> b
& ASetter UiVmState UiVmState (Set W256) (Set W256)
-> Set W256 -> UiVmState -> UiVmState
forall s t a b. ASetter s t a b -> b -> s -> t
set ASetter UiVmState UiVmState (Set W256) (Set W256)
Lens' UiVmState (Set W256)
uiVmSentHashes Set W256
sent
type Sexp = WellFormedSExpr HaskLikeAtom
prompt :: Console (Maybe Sexp)
prompt :: Console (Maybe Sexp)
prompt = do
String
line <- IO String -> StateT UiState IO String
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (String -> IO ()
putStr String
"> " IO () -> IO () -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Handle -> IO ()
hFlush Handle
stdout IO () -> IO String -> IO String
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> IO String
getLine)
case SExprParser HaskLikeAtom Sexp -> Text -> Either String Sexp
forall atom carrier.
SExprParser atom carrier -> Text -> Either String carrier
decodeOne (SExprParser HaskLikeAtom (SExpr HaskLikeAtom)
-> SExprParser HaskLikeAtom Sexp
forall a b.
SExprParser a (SExpr b) -> SExprParser a (WellFormedSExpr b)
asWellFormed SExprParser HaskLikeAtom (SExpr HaskLikeAtom)
haskLikeParser) (String -> Text
pack String
line) of
Left String
e -> do
SExpr Text -> Console ()
forall a. SDisplay a => a -> Console ()
output ([SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [Text -> SExpr Text
forall a. a -> SExpr a
A Text
"error", Text -> SExpr Text
forall a. a -> SExpr a
A (String -> Text
forall a. Show a => a -> Text
txt String
e)])
Maybe Sexp -> Console (Maybe Sexp)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Sexp
forall a. Maybe a
Nothing
Right Sexp
s ->
Maybe Sexp -> Console (Maybe Sexp)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Sexp -> Maybe Sexp
forall a. a -> Maybe a
Just Sexp
s)
class SDisplay a where
sexp :: a -> SExpr Text
display :: SDisplay a => a -> Text
display :: a -> Text
display = SExprPrinter Text (SExpr Text) -> SExpr Text -> Text
forall atom carrier. SExprPrinter atom carrier -> carrier -> Text
encodeOne ((Text -> Text) -> SExprPrinter Text (SExpr Text)
forall atom. (atom -> Text) -> SExprPrinter atom (SExpr atom)
basicPrint Text -> Text
forall a. a -> a
id) (SExpr Text -> Text) -> (a -> SExpr Text) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> SExpr Text
forall a. SDisplay a => a -> SExpr Text
sexp
txt :: Show a => a -> Text
txt :: a -> Text
txt = String -> Text
pack (String -> Text) -> (a -> String) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall a. Show a => a -> String
show
data UiState
= UiStarted
| UiDappLoaded DappInfo
| UiVm UiVmState
type Console a = StateT UiState IO a
output :: SDisplay a => a -> Console ()
output :: a -> Console ()
output = IO () -> Console ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> Console ()) -> (a -> IO ()) -> a -> Console ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> IO ()
putStrLn (String -> IO ()) -> (a -> String) -> a -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
unpack (Text -> String) -> (a -> Text) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Text
forall a. SDisplay a => a -> Text
display
main :: IO ()
main :: IO ()
main = do
String -> IO ()
putStrLn String
";; Welcome to Hevm's Emacs integration."
UiState
_ <- Console () -> UiState -> IO UiState
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m s
execStateT Console ()
loop UiState
UiStarted
() -> IO ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
loop :: Console ()
loop :: Console ()
loop =
Console (Maybe Sexp)
prompt Console (Maybe Sexp) -> (Maybe Sexp -> Console ()) -> Console ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
\case
Maybe Sexp
Nothing -> () -> Console ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
Just Sexp
command -> do
Sexp -> Console ()
handle Sexp
command
Console ()
loop
handle :: Sexp -> Console ()
handle :: Sexp -> Console ()
handle (WFSList (WFSAtom (HSIdent Text
cmd) : [Sexp]
args)) =
do UiState
s <- StateT UiState IO UiState
forall s (m :: * -> *). MonadState s m => m s
get
UiState -> (Text, [Sexp]) -> Console ()
handleCmd UiState
s (Text
cmd, [Sexp]
args)
handle Sexp
_ =
SExpr Text -> Console ()
forall a. SDisplay a => a -> Console ()
output ([SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [Text -> SExpr Text
forall a. a -> SExpr a
A (Text
"unrecognized-command" :: Text)])
handleCmd :: UiState -> (Text, [Sexp]) -> Console ()
handleCmd :: UiState -> (Text, [Sexp]) -> Console ()
handleCmd UiState
UiStarted = \case
(Text
"load-dapp",
[WFSAtom (HSString (Text -> String
unpack -> String
root)),
WFSAtom (HSString (Text -> String
unpack -> String
jsonPath))]) ->
do IO () -> Console ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (String -> IO ()
setCurrentDirectory String
root)
IO (Maybe (Map Text SolcContract, SourceCache))
-> StateT UiState IO (Maybe (Map Text SolcContract, SourceCache))
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (String -> IO (Maybe (Map Text SolcContract, SourceCache))
readSolc String
jsonPath) StateT UiState IO (Maybe (Map Text SolcContract, SourceCache))
-> (Maybe (Map Text SolcContract, SourceCache) -> Console ())
-> Console ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
\case
Maybe (Map Text SolcContract, SourceCache)
Nothing ->
SExpr Text -> Console ()
forall a. SDisplay a => a -> Console ()
output ([SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [Text -> SExpr Text
forall a. a -> SExpr a
A (Text
"error" :: Text)])
Just (Map Text SolcContract
contractMap, SourceCache
sourceCache) ->
let
dapp :: DappInfo
dapp = String -> Map Text SolcContract -> SourceCache -> DappInfo
dappInfo String
root Map Text SolcContract
contractMap SourceCache
sourceCache
in do
DappInfo -> Console ()
forall a. SDisplay a => a -> Console ()
output DappInfo
dapp
UiState -> Console ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put (DappInfo -> UiState
UiDappLoaded DappInfo
dapp)
(Text, [Sexp])
_ ->
SExpr Text -> Console ()
forall a. SDisplay a => a -> Console ()
output ([SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [Text -> SExpr Text
forall a. a -> SExpr a
A (Text
"unrecognized-command" :: Text)])
handleCmd (UiDappLoaded DappInfo
_) = \case
(Text
"run-test", [WFSAtom (HSString Text
contractPath),
WFSAtom (HSString Text
testName)]) -> do
UnitTestOptions
opts <- StateT UiState IO UnitTestOptions
forall (m :: * -> *). MonadIO m => m UnitTestOptions
defaultUnitTestOptions
UiState -> Console ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put (UiVmState -> UiState
UiVm (UnitTestOptions -> (Text, Text) -> UiVmState
initialStateForTest UnitTestOptions
opts (Text
contractPath, Text
testName)))
Console ()
outputVm
(Text, [Sexp])
_ ->
SExpr Text -> Console ()
forall a. SDisplay a => a -> Console ()
output ([SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [Text -> SExpr Text
forall a. a -> SExpr a
A (Text
"unrecognized-command" :: Text)])
handleCmd (UiVm UiVmState
s) = \case
(Text
"step", [WFSAtom (HSString Text
modeName)]) ->
case UiVmState -> Text -> Maybe StepMode
parseStepMode UiVmState
s Text
modeName of
Just StepMode
mode -> do
UiVmState -> StepPolicy -> StepMode -> Console ()
takeStep UiVmState
s StepPolicy
StepNormally StepMode
mode
Console ()
outputVm
Maybe StepMode
Nothing ->
SExpr Text -> Console ()
forall a. SDisplay a => a -> Console ()
output ([SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [Text -> SExpr Text
forall a. a -> SExpr a
A (Text
"unrecognized-command" :: Text)])
(Text
"step", [WFSList [ WFSAtom (HSString Text
"file-line")
, WFSAtom (HSString Text
fileName)
, WFSAtom (HSInt (Integer -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral -> Int
lineNumber))
]]) ->
case Getting (Maybe DappInfo) UiVmState (Maybe DappInfo)
-> UiVmState -> Maybe DappInfo
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting (Maybe DappInfo) UiVmState (Maybe DappInfo)
Lens' UiVmState (Maybe DappInfo)
uiVmDapp UiVmState
s of
Maybe DappInfo
Nothing ->
SExpr Text -> Console ()
forall a. SDisplay a => a -> Console ()
output ([SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [Text -> SExpr Text
forall a. a -> SExpr a
A (Text
"impossible" :: Text)])
Just DappInfo
dapp -> do
UiVmState -> StepPolicy -> StepMode -> Console ()
takeStep UiVmState
s StepPolicy
StepNormally
(Pred VM -> StepMode
StepUntil (DappInfo -> Text -> Int -> Pred VM
atFileLine DappInfo
dapp Text
fileName Int
lineNumber))
Console ()
outputVm
(Text, [Sexp])
_ ->
SExpr Text -> Console ()
forall a. SDisplay a => a -> Console ()
output ([SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [Text -> SExpr Text
forall a. a -> SExpr a
A (Text
"unrecognized-command" :: Text)])
atFileLine :: DappInfo -> Text -> Int -> VM -> Bool
atFileLine :: DappInfo -> Text -> Int -> Pred VM
atFileLine DappInfo
dapp Text
wantedFileName Int
wantedLineNumber VM
vm =
case DappInfo -> VM -> Maybe SrcMap
currentSrcMap DappInfo
dapp VM
vm of
Maybe SrcMap
Nothing -> Bool
False
Just SrcMap
sm ->
let
(Text
currentFileName, Int
currentLineNumber) =
Maybe (Text, Int) -> (Text, Int)
forall a. HasCallStack => Maybe a -> a
fromJust (SourceCache -> SrcMap -> Maybe (Text, Int)
srcMapCodePos (Getting SourceCache DappInfo SourceCache -> DappInfo -> SourceCache
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting SourceCache DappInfo SourceCache
Lens' DappInfo SourceCache
dappSources DappInfo
dapp) SrcMap
sm)
in
Text
currentFileName Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
wantedFileName Bool -> Bool -> Bool
&&
Int
currentLineNumber Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
wantedLineNumber
codeByHash :: W256 -> VM -> Maybe Buffer
codeByHash :: W256 -> VM -> Maybe Buffer
codeByHash W256
h VM
vm = do
let cs :: Map Addr Contract
cs = Getting (Map Addr Contract) VM (Map Addr Contract)
-> VM -> Map Addr Contract
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view ((Env -> Const (Map Addr Contract) Env)
-> VM -> Const (Map Addr Contract) VM
Lens' VM Env
env ((Env -> Const (Map Addr Contract) Env)
-> VM -> Const (Map Addr Contract) VM)
-> ((Map Addr Contract
-> Const (Map Addr Contract) (Map Addr Contract))
-> Env -> Const (Map Addr Contract) Env)
-> Getting (Map Addr Contract) VM (Map Addr Contract)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Map Addr Contract
-> Const (Map Addr Contract) (Map Addr Contract))
-> Env -> Const (Map Addr Contract) Env
Lens' Env (Map Addr Contract)
contracts) VM
vm
Contract
c <- (Contract -> Bool) -> [Contract] -> Maybe Contract
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
List.find (\Contract
c -> W256
h W256 -> W256 -> Bool
forall a. Eq a => a -> a -> Bool
== (Getting W256 Contract W256 -> Contract -> W256
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting W256 Contract W256
Lens' Contract W256
codehash Contract
c)) (Map Addr Contract -> [Contract]
forall k a. Map k a -> [a]
Map.elems Map Addr Contract
cs)
Buffer -> Maybe Buffer
forall (m :: * -> *) a. Monad m => a -> m a
return (Getting Buffer Contract Buffer -> Contract -> Buffer
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Buffer Contract Buffer
Getter Contract Buffer
bytecode Contract
c)
allHashes :: VM -> Set W256
allHashes :: VM -> Set W256
allHashes VM
vm = let cs :: Map Addr Contract
cs = Getting (Map Addr Contract) VM (Map Addr Contract)
-> VM -> Map Addr Contract
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view ((Env -> Const (Map Addr Contract) Env)
-> VM -> Const (Map Addr Contract) VM
Lens' VM Env
env ((Env -> Const (Map Addr Contract) Env)
-> VM -> Const (Map Addr Contract) VM)
-> ((Map Addr Contract
-> Const (Map Addr Contract) (Map Addr Contract))
-> Env -> Const (Map Addr Contract) Env)
-> Getting (Map Addr Contract) VM (Map Addr Contract)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Map Addr Contract
-> Const (Map Addr Contract) (Map Addr Contract))
-> Env -> Const (Map Addr Contract) Env
Lens' Env (Map Addr Contract)
contracts) VM
vm
in [W256] -> Set W256
forall a. Ord a => [a] -> Set a
Set.fromList ((Getting W256 Contract W256 -> Contract -> W256
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting W256 Contract W256
Lens' Contract W256
codehash) (Contract -> W256) -> [Contract] -> [W256]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map Addr Contract -> [Contract]
forall k a. Map k a -> [a]
Map.elems Map Addr Contract
cs)
outputVm :: Console ()
outputVm :: Console ()
outputVm = do
UiVm UiVmState
s <- StateT UiState IO UiState
forall s (m :: * -> *). MonadState s m => m s
get
let vm :: VM
vm = Getting VM UiVmState VM -> UiVmState -> VM
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting VM UiVmState VM
Lens' UiVmState VM
uiVm UiVmState
s
sendHashes :: Set W256
sendHashes = Set W256 -> Set W256 -> Set W256
forall a. Ord a => Set a -> Set a -> Set a
Set.difference (VM -> Set W256
allHashes VM
vm) (Getting (Set W256) UiVmState (Set W256) -> UiVmState -> Set W256
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting (Set W256) UiVmState (Set W256)
Lens' UiVmState (Set W256)
uiVmSentHashes UiVmState
s)
sendCodes :: Map W256 (Maybe Buffer)
sendCodes = (W256 -> Maybe Buffer) -> Set W256 -> Map W256 (Maybe Buffer)
forall k a. (k -> a) -> Set k -> Map k a
Map.fromSet (W256 -> VM -> Maybe Buffer
`codeByHash` VM
vm) Set W256
sendHashes
noMap :: Console ()
noMap =
SExpr Text -> Console ()
forall a. SDisplay a => a -> Console ()
output (SExpr Text -> Console ()) -> SExpr Text -> Console ()
forall a b. (a -> b) -> a -> b
$
[SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [ Text -> SExpr Text
forall a. a -> SExpr a
A Text
"step"
, [SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [Text -> SExpr Text
forall a. a -> SExpr a
A (Text
"vm" :: Text), VM -> SExpr Text
forall a. SDisplay a => a -> SExpr Text
sexp (Getting VM UiVmState VM -> UiVmState -> VM
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting VM UiVmState VM
Lens' UiVmState VM
uiVm UiVmState
s)]
]
Console () -> Maybe (Console ()) -> Console ()
forall a. a -> Maybe a -> a
fromMaybe Console ()
noMap (Maybe (Console ()) -> Console ())
-> Maybe (Console ()) -> Console ()
forall a b. (a -> b) -> a -> b
$ do
DappInfo
dapp <- Getting (Maybe DappInfo) UiVmState (Maybe DappInfo)
-> UiVmState -> Maybe DappInfo
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting (Maybe DappInfo) UiVmState (Maybe DappInfo)
Lens' UiVmState (Maybe DappInfo)
uiVmDapp UiVmState
s
SrcMap
sm <- DappInfo -> VM -> Maybe SrcMap
currentSrcMap DappInfo
dapp (Getting VM UiVmState VM -> UiVmState -> VM
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting VM UiVmState VM
Lens' UiVmState VM
uiVm UiVmState
s)
let (Text
fileName, ByteString
_) = Getting [(Text, ByteString)] DappInfo [(Text, ByteString)]
-> DappInfo -> [(Text, ByteString)]
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view ((SourceCache -> Const [(Text, ByteString)] SourceCache)
-> DappInfo -> Const [(Text, ByteString)] DappInfo
Lens' DappInfo SourceCache
dappSources ((SourceCache -> Const [(Text, ByteString)] SourceCache)
-> DappInfo -> Const [(Text, ByteString)] DappInfo)
-> (([(Text, ByteString)]
-> Const [(Text, ByteString)] [(Text, ByteString)])
-> SourceCache -> Const [(Text, ByteString)] SourceCache)
-> Getting [(Text, ByteString)] DappInfo [(Text, ByteString)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([(Text, ByteString)]
-> Const [(Text, ByteString)] [(Text, ByteString)])
-> SourceCache -> Const [(Text, ByteString)] SourceCache
Lens' SourceCache [(Text, ByteString)]
sourceFiles) DappInfo
dapp [(Text, ByteString)] -> Int -> (Text, ByteString)
forall a. [a] -> Int -> a
!! SrcMap -> Int
srcMapFile SrcMap
sm
Console () -> Maybe (Console ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Console () -> Maybe (Console ()))
-> (SExpr Text -> Console ()) -> SExpr Text -> Maybe (Console ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SExpr Text -> Console ()
forall a. SDisplay a => a -> Console ()
output (SExpr Text -> Maybe (Console ()))
-> SExpr Text -> Maybe (Console ())
forall a b. (a -> b) -> a -> b
$
[SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [ Text -> SExpr Text
forall a. a -> SExpr a
A Text
"step"
, [SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [Text -> SExpr Text
forall a. a -> SExpr a
A (Text
"vm" :: Text), VM -> SExpr Text
forall a. SDisplay a => a -> SExpr Text
sexp (Getting VM UiVmState VM -> UiVmState -> VM
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting VM UiVmState VM
Lens' UiVmState VM
uiVm UiVmState
s)]
, [SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [Text -> SExpr Text
forall a. a -> SExpr a
A (Text
"file" :: Text), Text -> SExpr Text
forall a. a -> SExpr a
A (Text -> Text
forall a. Show a => a -> Text
txt Text
fileName)]
, [SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [ Text -> SExpr Text
forall a. a -> SExpr a
A (Text
"srcmap" :: Text)
, Text -> SExpr Text
forall a. a -> SExpr a
A (Int -> Text
forall a. Show a => a -> Text
txt (SrcMap -> Int
srcMapOffset SrcMap
sm))
, Text -> SExpr Text
forall a. a -> SExpr a
A (Int -> Text
forall a. Show a => a -> Text
txt (SrcMap -> Int
srcMapLength SrcMap
sm))
, Text -> SExpr Text
forall a. a -> SExpr a
A (JumpType -> Text
forall a. Show a => a -> Text
txt (SrcMap -> JumpType
srcMapJump SrcMap
sm))
]
]
isNextSourcePosition
:: UiVmState -> Pred VM
isNextSourcePosition :: UiVmState -> Pred VM
isNextSourcePosition UiVmState
ui VM
vm =
let
Just DappInfo
dapp = Getting (Maybe DappInfo) UiVmState (Maybe DappInfo)
-> UiVmState -> Maybe DappInfo
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting (Maybe DappInfo) UiVmState (Maybe DappInfo)
Lens' UiVmState (Maybe DappInfo)
uiVmDapp UiVmState
ui
initialPosition :: Maybe SrcMap
initialPosition = DappInfo -> VM -> Maybe SrcMap
currentSrcMap DappInfo
dapp (Getting VM UiVmState VM -> UiVmState -> VM
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting VM UiVmState VM
Lens' UiVmState VM
uiVm UiVmState
ui)
in
DappInfo -> VM -> Maybe SrcMap
currentSrcMap DappInfo
dapp VM
vm Maybe SrcMap -> Maybe SrcMap -> Bool
forall a. Eq a => a -> a -> Bool
/= Maybe SrcMap
initialPosition
parseStepMode :: UiVmState -> Text -> Maybe StepMode
parseStepMode :: UiVmState -> Text -> Maybe StepMode
parseStepMode UiVmState
s =
\case
Text
"once" -> StepMode -> Maybe StepMode
forall a. a -> Maybe a
Just StepMode
StepOne
Text
"source-location" -> StepMode -> Maybe StepMode
forall a. a -> Maybe a
Just (Pred VM -> StepMode
StepUntil (UiVmState -> Pred VM
isNextSourcePosition UiVmState
s))
Text
_ -> Maybe StepMode
forall a. Maybe a
Nothing
data StepPolicy
= StepNormally
| StepTimidly
takeStep
:: UiVmState
-> StepPolicy
-> StepMode
-> Console ()
takeStep :: UiVmState -> StepPolicy -> StepMode -> Console ()
takeStep UiVmState
ui StepPolicy
policy StepMode
mode = do
let m :: State UiVmState (StepOutcome ())
m = StepMode -> Stepper () -> State UiVmState (StepOutcome ())
forall a. StepMode -> Stepper a -> State UiVmState (StepOutcome a)
interpret StepMode
mode (Getting (Stepper ()) UiVmState (Stepper ())
-> UiVmState -> Stepper ()
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting (Stepper ()) UiVmState (Stepper ())
Lens' UiVmState (Stepper ())
uiVmNextStep UiVmState
ui)
case State UiVmState (StepOutcome ())
-> UiVmState -> (StepOutcome (), UiVmState)
forall s a. State s a -> s -> (a, s)
runState State UiVmState (StepOutcome ())
m UiVmState
ui of
(Stepped Stepper ()
stepper, UiVmState
ui') ->
UiState -> Console ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put (UiVmState -> UiState
UiVm (UiVmState
ui' UiVmState -> (UiVmState -> UiVmState) -> UiVmState
forall a b. a -> (a -> b) -> b
& ASetter UiVmState UiVmState (Stepper ()) (Stepper ())
-> Stepper () -> UiVmState -> UiVmState
forall s t a b. ASetter s t a b -> b -> s -> t
set ASetter UiVmState UiVmState (Stepper ()) (Stepper ())
Lens' UiVmState (Stepper ())
uiVmNextStep Stepper ()
stepper))
(Blocked IO (Stepper ())
blocker, UiVmState
ui') ->
case StepPolicy
policy of
StepPolicy
StepNormally -> do
Stepper ()
stepper <- IO (Stepper ()) -> StateT UiState IO (Stepper ())
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO (Stepper ())
blocker
UiVmState -> StepPolicy -> StepMode -> Console ()
takeStep
(StateT UiVmState Identity () -> UiVmState -> UiVmState
forall s a. State s a -> s -> s
execState (ASetter UiVmState UiVmState (Stepper ()) (Stepper ())
-> Stepper () -> StateT UiVmState Identity ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
assign ASetter UiVmState UiVmState (Stepper ()) (Stepper ())
Lens' UiVmState (Stepper ())
uiVmNextStep Stepper ()
stepper) UiVmState
ui')
StepPolicy
StepNormally StepMode
StepNone
StepPolicy
StepTimidly ->
String -> Console ()
forall a. HasCallStack => String -> a
error String
"step blocked unexpectedly"
(Returned (), UiVmState
ui') ->
case StepPolicy
policy of
StepPolicy
StepNormally ->
UiState -> Console ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put (UiVmState -> UiState
UiVm UiVmState
ui')
StepPolicy
StepTimidly ->
String -> Console ()
forall a. HasCallStack => String -> a
error String
"step halted unexpectedly"
instance SDisplay DappInfo where
sexp :: DappInfo -> SExpr Text
sexp DappInfo
x =
[SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [ Text -> SExpr Text
forall a. a -> SExpr a
A Text
"dapp-info"
, [SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [Text -> SExpr Text
forall a. a -> SExpr a
A Text
"root", Text -> SExpr Text
forall a. a -> SExpr a
A (String -> Text
forall a. Show a => a -> Text
txt (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ Getting String DappInfo String -> DappInfo -> String
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting String DappInfo String
Lens' DappInfo String
dappRoot DappInfo
x)]
, [SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L (Text -> SExpr Text
forall a. a -> SExpr a
A Text
"unit-tests" SExpr Text -> [SExpr Text] -> [SExpr Text]
forall a. a -> [a] -> [a]
:
[ [SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [Text -> SExpr Text
forall a. a -> SExpr a
A (Text -> Text
forall a. Show a => a -> Text
txt Text
a), [SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L (((Test, [AbiType]) -> SExpr Text)
-> [(Test, [AbiType])] -> [SExpr Text]
forall a b. (a -> b) -> [a] -> [b]
map (Text -> SExpr Text
forall a. a -> SExpr a
A (Text -> SExpr Text)
-> ((Test, [AbiType]) -> Text) -> (Test, [AbiType]) -> SExpr Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Test, [AbiType]) -> Text
forall a. Show a => a -> Text
txt) [(Test, [AbiType])]
b)]
| (Text
a, [(Test, [AbiType])]
b) <- Getting
[(Text, [(Test, [AbiType])])]
DappInfo
[(Text, [(Test, [AbiType])])]
-> DappInfo -> [(Text, [(Test, [AbiType])])]
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting
[(Text, [(Test, [AbiType])])]
DappInfo
[(Text, [(Test, [AbiType])])]
Lens' DappInfo [(Text, [(Test, [AbiType])])]
dappUnitTests DappInfo
x])
]
instance SDisplay (SExpr Text) where
sexp :: SExpr Text -> SExpr Text
sexp = SExpr Text -> SExpr Text
forall a. a -> a
id
instance SDisplay Storage where
sexp :: Storage -> SExpr Text
sexp (Symbolic [(SymWord, SymWord)]
_ SArray (WordN 256) (WordN 256)
_) = String -> SExpr Text
forall a. HasCallStack => String -> a
error String
"idk"
sexp (Concrete Map Word SymWord
d) = Map Word SymWord -> SExpr Text
forall a. SDisplay a => a -> SExpr Text
sexp Map Word SymWord
d
instance SDisplay VM where
sexp :: VM -> SExpr Text
sexp VM
x =
[SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [ [SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [Text -> SExpr Text
forall a. a -> SExpr a
A Text
"result", Maybe VMResult -> SExpr Text
forall a. SDisplay a => a -> SExpr Text
sexp (((Maybe VMResult -> Const (Maybe VMResult) (Maybe VMResult))
-> VM -> Const (Maybe VMResult) VM)
-> VM -> Maybe VMResult
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view (Maybe VMResult -> Const (Maybe VMResult) (Maybe VMResult))
-> VM -> Const (Maybe VMResult) VM
Lens' VM (Maybe VMResult)
result VM
x)]
, [SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [Text -> SExpr Text
forall a. a -> SExpr a
A Text
"state", FrameState -> SExpr Text
forall a. SDisplay a => a -> SExpr Text
sexp (Getting FrameState VM FrameState -> VM -> FrameState
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting FrameState VM FrameState
Lens' VM FrameState
state VM
x)]
, [SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [Text -> SExpr Text
forall a. a -> SExpr a
A Text
"frames", [Frame] -> SExpr Text
forall a. SDisplay a => a -> SExpr Text
sexp (Getting [Frame] VM [Frame] -> VM -> [Frame]
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting [Frame] VM [Frame]
Lens' VM [Frame]
frames VM
x)]
, [SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [Text -> SExpr Text
forall a. a -> SExpr a
A Text
"contracts", Map Addr Contract -> SExpr Text
forall a. SDisplay a => a -> SExpr Text
sexp (Getting (Map Addr Contract) VM (Map Addr Contract)
-> VM -> Map Addr Contract
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view ((Env -> Const (Map Addr Contract) Env)
-> VM -> Const (Map Addr Contract) VM
Lens' VM Env
env ((Env -> Const (Map Addr Contract) Env)
-> VM -> Const (Map Addr Contract) VM)
-> ((Map Addr Contract
-> Const (Map Addr Contract) (Map Addr Contract))
-> Env -> Const (Map Addr Contract) Env)
-> Getting (Map Addr Contract) VM (Map Addr Contract)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Map Addr Contract
-> Const (Map Addr Contract) (Map Addr Contract))
-> Env -> Const (Map Addr Contract) Env
Lens' Env (Map Addr Contract)
contracts) VM
x)]
]
quoted :: Text -> Text
quoted :: Text -> Text
quoted Text
x = Text
"\"" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
x Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\""
instance SDisplay Addr where
sexp :: Addr -> SExpr Text
sexp = Text -> SExpr Text
forall a. a -> SExpr a
A (Text -> SExpr Text) -> (Addr -> Text) -> Addr -> SExpr Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
quoted (Text -> Text) -> (Addr -> Text) -> Addr -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
pack (String -> Text) -> (Addr -> String) -> Addr -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Addr -> String
forall a. Show a => a -> String
show
instance SDisplay Contract where
sexp :: Contract -> SExpr Text
sexp Contract
x =
[SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [ [SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [Text -> SExpr Text
forall a. a -> SExpr a
A Text
"storage", Storage -> SExpr Text
forall a. SDisplay a => a -> SExpr Text
sexp (Getting Storage Contract Storage -> Contract -> Storage
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Storage Contract Storage
Lens' Contract Storage
storage Contract
x)]
, [SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [Text -> SExpr Text
forall a. a -> SExpr a
A Text
"balance", Word -> SExpr Text
forall a. SDisplay a => a -> SExpr Text
sexp (Getting Word Contract Word -> Contract -> Word
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Word Contract Word
Lens' Contract Word
balance Contract
x)]
, [SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [Text -> SExpr Text
forall a. a -> SExpr a
A Text
"nonce", Word -> SExpr Text
forall a. SDisplay a => a -> SExpr Text
sexp (Getting Word Contract Word -> Contract -> Word
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Word Contract Word
Lens' Contract Word
nonce Contract
x)]
, [SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [Text -> SExpr Text
forall a. a -> SExpr a
A Text
"codehash", W256 -> SExpr Text
forall a. SDisplay a => a -> SExpr Text
sexp (Getting W256 Contract W256 -> Contract -> W256
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting W256 Contract W256
Lens' Contract W256
codehash Contract
x)]
]
instance SDisplay W256 where
sexp :: W256 -> SExpr Text
sexp W256
x = Text -> SExpr Text
forall a. a -> SExpr a
A (Text -> Text
forall a. Show a => a -> Text
txt (W256 -> Text
forall a. Show a => a -> Text
txt W256
x))
instance SDisplay (SWord 256) where
sexp :: SWord 256 -> SExpr Text
sexp SWord 256
x = Text -> SExpr Text
forall a. a -> SExpr a
A (Text -> Text
forall a. Show a => a -> Text
txt (SWord 256 -> Text
forall a. Show a => a -> Text
txt SWord 256
x))
instance SDisplay (SymWord) where
sexp :: SymWord -> SExpr Text
sexp SymWord
x = Text -> SExpr Text
forall a. a -> SExpr a
A (Text -> Text
forall a. Show a => a -> Text
txt (SymWord -> Text
forall a. Show a => a -> Text
txt SymWord
x))
instance SDisplay (SWord 8) where
sexp :: SWord 8 -> SExpr Text
sexp SWord 8
x = Text -> SExpr Text
forall a. a -> SExpr a
A (Text -> Text
forall a. Show a => a -> Text
txt (SWord 8 -> Text
forall a. Show a => a -> Text
txt SWord 8
x))
instance SDisplay Buffer where
sexp :: Buffer -> SExpr Text
sexp (SymbolicBuffer [SWord 8]
x) = [SWord 8] -> SExpr Text
forall a. SDisplay a => a -> SExpr Text
sexp [SWord 8]
x
sexp (ConcreteBuffer ByteString
x) = ByteString -> SExpr Text
forall a. SDisplay a => a -> SExpr Text
sexp ByteString
x
instance (SDisplay k, SDisplay v) => SDisplay (Map k v) where
sexp :: Map k v -> SExpr Text
sexp Map k v
x = [SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [[SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [k -> SExpr Text
forall a. SDisplay a => a -> SExpr Text
sexp k
k, v -> SExpr Text
forall a. SDisplay a => a -> SExpr Text
sexp v
v] | (k
k, v
v) <- Map k v -> [(k, v)]
forall k a. Map k a -> [(k, a)]
Map.toList Map k v
x]
instance SDisplay a => SDisplay (Maybe a) where
sexp :: Maybe a -> SExpr Text
sexp Maybe a
Nothing = Text -> SExpr Text
forall a. a -> SExpr a
A Text
"nil"
sexp (Just a
x) = a -> SExpr Text
forall a. SDisplay a => a -> SExpr Text
sexp a
x
instance SDisplay VMResult where
sexp :: VMResult -> SExpr Text
sexp = \case
VMFailure Error
e -> [SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [Text -> SExpr Text
forall a. a -> SExpr a
A Text
"vm-failure", Text -> SExpr Text
forall a. a -> SExpr a
A (Text -> Text
forall a. Show a => a -> Text
txt (Error -> Text
forall a. Show a => a -> Text
txt Error
e))]
VMSuccess Buffer
b -> [SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [Text -> SExpr Text
forall a. a -> SExpr a
A Text
"vm-success", Buffer -> SExpr Text
forall a. SDisplay a => a -> SExpr Text
sexp Buffer
b]
instance SDisplay Frame where
sexp :: Frame -> SExpr Text
sexp Frame
x =
[SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [Text -> SExpr Text
forall a. a -> SExpr a
A Text
"frame", FrameContext -> SExpr Text
forall a. SDisplay a => a -> SExpr Text
sexp (Getting FrameContext Frame FrameContext -> Frame -> FrameContext
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting FrameContext Frame FrameContext
Lens' Frame FrameContext
frameContext Frame
x), FrameState -> SExpr Text
forall a. SDisplay a => a -> SExpr Text
sexp (Getting FrameState Frame FrameState -> Frame -> FrameState
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting FrameState Frame FrameState
Lens' Frame FrameState
frameState Frame
x)]
instance SDisplay FrameContext where
sexp :: FrameContext -> SExpr Text
sexp FrameContext
_x = Text -> SExpr Text
forall a. a -> SExpr a
A Text
"some-context"
instance SDisplay FrameState where
sexp :: FrameState -> SExpr Text
sexp FrameState
x =
[SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [ [SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [Text -> SExpr Text
forall a. a -> SExpr a
A Text
"contract", Addr -> SExpr Text
forall a. SDisplay a => a -> SExpr Text
sexp (Getting Addr FrameState Addr -> FrameState -> Addr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Addr FrameState Addr
Lens' FrameState Addr
contract FrameState
x)]
, [SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [Text -> SExpr Text
forall a. a -> SExpr a
A Text
"code-contract", Addr -> SExpr Text
forall a. SDisplay a => a -> SExpr Text
sexp (Getting Addr FrameState Addr -> FrameState -> Addr
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Addr FrameState Addr
Lens' FrameState Addr
codeContract FrameState
x)]
, [SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [Text -> SExpr Text
forall a. a -> SExpr a
A Text
"pc", Text -> SExpr Text
forall a. a -> SExpr a
A (Int -> Text
forall a. Show a => a -> Text
txt (Getting Int FrameState Int -> FrameState -> Int
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Int FrameState Int
Lens' FrameState Int
pc FrameState
x))]
, [SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [Text -> SExpr Text
forall a. a -> SExpr a
A Text
"stack", [SymWord] -> SExpr Text
forall a. SDisplay a => a -> SExpr Text
sexp (Getting [SymWord] FrameState [SymWord] -> FrameState -> [SymWord]
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting [SymWord] FrameState [SymWord]
Lens' FrameState [SymWord]
stack FrameState
x)]
, [SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [Text -> SExpr Text
forall a. a -> SExpr a
A Text
"memory", Buffer -> SExpr Text
sexpMemory (Getting Buffer FrameState Buffer -> FrameState -> Buffer
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Buffer FrameState Buffer
Lens' FrameState Buffer
memory FrameState
x)]
]
instance SDisplay a => SDisplay [a] where
sexp :: [a] -> SExpr Text
sexp = [SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L ([SExpr Text] -> SExpr Text)
-> ([a] -> [SExpr Text]) -> [a] -> SExpr Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> SExpr Text) -> [a] -> [SExpr Text]
forall a b. (a -> b) -> [a] -> [b]
map a -> SExpr Text
forall a. SDisplay a => a -> SExpr Text
sexp
instance {-# OVERLAPPING #-} SDisplay String where
sexp :: String -> SExpr Text
sexp String
x = Text -> SExpr Text
forall a. a -> SExpr a
A (String -> Text
forall a. Show a => a -> Text
txt String
x)
instance SDisplay Word where
sexp :: Word -> SExpr Text
sexp (C (FromKeccak Buffer
bs) W256
x) =
[SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [Text -> SExpr Text
forall a. a -> SExpr a
A Text
"hash", Text -> SExpr Text
forall a. a -> SExpr a
A (W256 -> Text
forall a. Show a => a -> Text
txt W256
x), Buffer -> SExpr Text
forall a. SDisplay a => a -> SExpr Text
sexp Buffer
bs]
sexp (C Whiff
_ W256
x) = Text -> SExpr Text
forall a. a -> SExpr a
A (Text -> Text
quoted (W256 -> Text
forall a. Show a => a -> Text
txt W256
x))
instance SDisplay ByteString where
sexp :: ByteString -> SExpr Text
sexp = Text -> SExpr Text
forall a. a -> SExpr a
A (Text -> SExpr Text)
-> (ByteString -> Text) -> ByteString -> SExpr Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
forall a. Show a => a -> Text
txt (Text -> Text) -> (ByteString -> Text) -> ByteString -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
pack (String -> Text) -> (ByteString -> String) -> ByteString -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteStringS -> String
forall a. Show a => a -> String
show (ByteStringS -> String)
-> (ByteString -> ByteStringS) -> ByteString -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteStringS
ByteStringS
sexpMemory :: Buffer -> SExpr Text
sexpMemory :: Buffer -> SExpr Text
sexpMemory Buffer
bs =
if Buffer -> Int
len Buffer
bs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1024
then [SExpr Text] -> SExpr Text
forall a. [SExpr a] -> SExpr a
L [Text -> SExpr Text
forall a. a -> SExpr a
A Text
"large-memory", Text -> SExpr Text
forall a. a -> SExpr a
A (Int -> Text
forall a. Show a => a -> Text
txt (Buffer -> Int
len Buffer
bs))]
else Buffer -> SExpr Text
forall a. SDisplay a => a -> SExpr Text
sexp Buffer
bs
defaultUnitTestOptions :: MonadIO m => m UnitTestOptions
defaultUnitTestOptions :: m UnitTestOptions
defaultUnitTestOptions = do
TestVMParams
params <- IO TestVMParams -> m TestVMParams
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO TestVMParams -> m TestVMParams)
-> IO TestVMParams -> m TestVMParams
forall a b. (a -> b) -> a -> b
$ Maybe Text -> IO TestVMParams
getParametersFromEnvironmentVariables Maybe Text
forall a. Maybe a
Nothing
UnitTestOptions -> m UnitTestOptions
forall (f :: * -> *) a. Applicative f => a -> f a
pure UnitTestOptions :: Fetcher
-> Maybe Int
-> Maybe Integer
-> Maybe Integer
-> Maybe Int
-> Maybe Integer
-> Maybe State
-> Maybe Text
-> Maybe Text
-> Text
-> Int
-> Maybe (Text, ByteString)
-> (VM -> VM)
-> DappInfo
-> TestVMParams
-> Bool
-> UnitTestOptions
UnitTestOptions
{ oracle :: Fetcher
oracle = Fetcher
Fetch.zero
, verbose :: Maybe Int
verbose = Maybe Int
forall a. Maybe a
Nothing
, maxIter :: Maybe Integer
maxIter = Maybe Integer
forall a. Maybe a
Nothing
, askSmtIters :: Maybe Integer
askSmtIters = Maybe Integer
forall a. Maybe a
Nothing
, smtTimeout :: Maybe Integer
smtTimeout = Maybe Integer
forall a. Maybe a
Nothing
, smtState :: Maybe State
smtState = Maybe State
forall a. Maybe a
Nothing
, solver :: Maybe Text
solver = Maybe Text
forall a. Maybe a
Nothing
, match :: Text
match = Text
""
, covMatch :: Maybe Text
covMatch = Maybe Text
forall a. Maybe a
Nothing
, fuzzRuns :: Int
fuzzRuns = Int
100
, replay :: Maybe (Text, ByteString)
replay = Maybe (Text, ByteString)
forall a. Maybe a
Nothing
, vmModifier :: VM -> VM
vmModifier = VM -> VM
forall a. a -> a
id
, dapp :: DappInfo
dapp = DappInfo
emptyDapp
, testParams :: TestVMParams
testParams = TestVMParams
params
, maxDepth :: Maybe Int
maxDepth = Maybe Int
forall a. Maybe a
Nothing
, ffiAllowed :: Bool
ffiAllowed = Bool
False
}
initialStateForTest
:: UnitTestOptions
-> (Text, Text)
-> UiVmState
initialStateForTest :: UnitTestOptions -> (Text, Text) -> UiVmState
initialStateForTest opts :: UnitTestOptions
opts@(UnitTestOptions {Bool
Int
Maybe Int
Maybe Integer
Maybe (Text, ByteString)
Maybe Text
Maybe State
Text
DappInfo
TestVMParams
Fetcher
VM -> VM
ffiAllowed :: Bool
testParams :: TestVMParams
dapp :: DappInfo
vmModifier :: VM -> VM
replay :: Maybe (Text, ByteString)
fuzzRuns :: Int
match :: Text
covMatch :: Maybe Text
solver :: Maybe Text
smtState :: Maybe State
smtTimeout :: Maybe Integer
maxDepth :: Maybe Int
askSmtIters :: Maybe Integer
maxIter :: Maybe Integer
verbose :: Maybe Int
oracle :: Fetcher
ffiAllowed :: UnitTestOptions -> Bool
maxDepth :: UnitTestOptions -> Maybe Int
testParams :: UnitTestOptions -> TestVMParams
dapp :: UnitTestOptions -> DappInfo
vmModifier :: UnitTestOptions -> VM -> VM
replay :: UnitTestOptions -> Maybe (Text, ByteString)
fuzzRuns :: UnitTestOptions -> Int
covMatch :: UnitTestOptions -> Maybe Text
match :: UnitTestOptions -> Text
solver :: UnitTestOptions -> Maybe Text
smtState :: UnitTestOptions -> Maybe State
smtTimeout :: UnitTestOptions -> Maybe Integer
askSmtIters :: UnitTestOptions -> Maybe Integer
maxIter :: UnitTestOptions -> Maybe Integer
verbose :: UnitTestOptions -> Maybe Int
oracle :: UnitTestOptions -> Fetcher
..}) (Text
contractPath, Text
testName) =
UiVmState
ui1
where
script :: Stepper ()
script = do
EVM () -> Stepper ()
forall a. EVM a -> Stepper a
Stepper.evm (EVM () -> Stepper ()) -> (Text -> EVM ()) -> Text -> Stepper ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TraceData -> EVM ()
pushTrace (TraceData -> EVM ()) -> (Text -> TraceData) -> Text -> EVM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> TraceData
EntryTrace (Text -> Stepper ()) -> Text -> Stepper ()
forall a b. (a -> b) -> a -> b
$
Text
"test " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
testName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" (" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
contractPath Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
UnitTestOptions -> SolcContract -> Stepper ()
initializeUnitTest UnitTestOptions
opts SolcContract
testContract
ProgramT Action Identity Bool -> Stepper ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (UnitTestOptions
-> Text -> AbiValue -> ProgramT Action Identity Bool
runUnitTest UnitTestOptions
opts Text
testName (Vector AbiValue -> AbiValue
AbiTuple Vector AbiValue
forall a. Monoid a => a
mempty))
ui0 :: UiVmState
ui0 =
UiVmState :: VM
-> Stepper ()
-> Maybe SolcContract
-> Maybe DappInfo
-> Int
-> UiVmState
-> Fetcher
-> Maybe Text
-> Set W256
-> UiVmState
UiVmState
{ _uiVm :: VM
_uiVm = VM
vm0
, _uiVmNextStep :: Stepper ()
_uiVmNextStep = Stepper ()
script
, _uiVmSolc :: Maybe SolcContract
_uiVmSolc = SolcContract -> Maybe SolcContract
forall a. a -> Maybe a
Just SolcContract
testContract
, _uiVmDapp :: Maybe DappInfo
_uiVmDapp = Maybe DappInfo
forall a. Maybe a
Nothing
, _uiVmStepCount :: Int
_uiVmStepCount = Int
0
, _uiVmFirstState :: UiVmState
_uiVmFirstState = UiVmState
forall a. HasCallStack => a
undefined
, _uiVmFetcher :: Fetcher
_uiVmFetcher = Fetcher
oracle
, _uiVmMessage :: Maybe Text
_uiVmMessage = Maybe Text
forall a. Maybe a
Nothing
, _uiVmSentHashes :: Set W256
_uiVmSentHashes = Set W256
forall a. Set a
Set.empty
}
Just SolcContract
testContract =
Getting (Maybe SolcContract) DappInfo (Maybe SolcContract)
-> DappInfo -> Maybe SolcContract
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view ((Map Text SolcContract
-> Const (Maybe SolcContract) (Map Text SolcContract))
-> DappInfo -> Const (Maybe SolcContract) DappInfo
Lens' DappInfo (Map Text SolcContract)
dappSolcByName ((Map Text SolcContract
-> Const (Maybe SolcContract) (Map Text SolcContract))
-> DappInfo -> Const (Maybe SolcContract) DappInfo)
-> ((Maybe SolcContract
-> Const (Maybe SolcContract) (Maybe SolcContract))
-> Map Text SolcContract
-> Const (Maybe SolcContract) (Map Text SolcContract))
-> Getting (Maybe SolcContract) DappInfo (Maybe SolcContract)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Index (Map Text SolcContract)
-> Lens'
(Map Text SolcContract) (Maybe (IxValue (Map Text SolcContract)))
forall m. At m => Index m -> Lens' m (Maybe (IxValue m))
at Text
Index (Map Text SolcContract)
contractPath) DappInfo
dapp
vm0 :: VM
vm0 =
UnitTestOptions -> SolcContract -> VM
initialUnitTestVm UnitTestOptions
opts SolcContract
testContract
ui1 :: UiVmState
ui1 =
UiVmState -> VM -> UiVmState
updateUiVmState UiVmState
ui0 VM
vm0 UiVmState -> (UiVmState -> UiVmState) -> UiVmState
forall a b. a -> (a -> b) -> b
& ASetter UiVmState UiVmState UiVmState UiVmState
-> UiVmState -> UiVmState -> UiVmState
forall s t a b. ASetter s t a b -> b -> s -> t
set ASetter UiVmState UiVmState UiVmState UiVmState
Lens' UiVmState UiVmState
uiVmFirstState UiVmState
ui1