Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Call stacks #995

Merged
merged 27 commits into from
Dec 9, 2020
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
d40d6b4
Retain source position annotations from the parsed AST
robdockins Nov 23, 2020
4454a1e
Remove instances of immediately-nested location information annotations.
robdockins Nov 26, 2020
744fcfd
Get better output from `displayException` when throwing EvalError.
robdockins Nov 24, 2020
ef442be
Refactor how primitives are represented. We invent a lightweight syntax
robdockins Nov 24, 2020
3698051
Add source-location tracking when calling primitives.
robdockins Nov 24, 2020
d7ade02
Handle WordToWide exceptions along with the other runtime exception
robdockins Nov 25, 2020
0aeb053
Add line number counting for batch mode and interactive
robdockins Nov 26, 2020
80b558a
When safey violations are found via `:safe` or `:prove`, run
robdockins Nov 26, 2020
5c116e2
Fix test golden output: runtime errors now print source locations.
robdockins Nov 25, 2020
81ca04f
remove some stray code
robdockins Dec 1, 2020
eaf3746
Improve source location tracking for <<loop>> errors
robdockins Dec 1, 2020
553cbad
Remove the mostly-unused message argument to `sDelay`
robdockins Dec 1, 2020
d0f39d1
Add support for call stacks to the Cryptol interpreter.
robdockins Dec 3, 2020
b635a51
Update test suite with backtraces
robdockins Dec 3, 2020
fe7c458
Remove the `Range` argument from most backend functions and
robdockins Dec 7, 2020
899b433
Make sure that `error` properly tracks the call stack
robdockins Dec 7, 2020
ec1ce3c
Don't print trivial position information
robdockins Dec 7, 2020
d60b4f0
Add range information for auto-generated errors when
robdockins Dec 7, 2020
cec83cc
Updates to test results
robdockins Dec 7, 2020
bdfefd5
squash a warning
robdockins Dec 7, 2020
f533b23
Be more precise about propigating call stacks in a few places
robdockins Dec 7, 2020
105466b
Add comments and minor cleanups
robdockins Dec 7, 2020
1ae651a
Add a new `--no-call-stacks` command line option that disables
robdockins Dec 9, 2020
3d117e4
Introduce a record datatype for the inputs to module commands.
robdockins Dec 9, 2020
61f4dc0
update CHANGES.md
robdockins Dec 9, 2020
b5d66ff
Add a `sWithCallStack` method to capure a common pattern. Minor clea…
robdockins Dec 9, 2020
b273e6d
Minor improvements to range tracking
robdockins Dec 9, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion cryptol-remote-api/src/CryptolServer/Data/Expression.hs
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ readBack :: PrimMap -> TC.Type -> Value -> Eval Expression
readBack prims ty val =
let tbl = primTable theEvalOpts in
let ?evalPrim = \i -> Right <$> Map.lookup i tbl in
let ?range = emptyRange in -- TODO?
case TC.tNoUser ty of
TC.TRec tfs ->
Record . HM.fromList <$>
Expand Down Expand Up @@ -369,7 +370,7 @@ readBack prims ty val =


observe :: Eval a -> Method ServerState a
observe e = liftIO (runEval e)
observe e = liftIO (runEval mempty e)

mkEApp :: Expr PName -> [Expr PName] -> Expr PName
mkEApp f args = foldl EApp f args
1 change: 1 addition & 0 deletions cryptol.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ library
Cryptol.Eval.Concrete,
Cryptol.Eval.Env,
Cryptol.Eval.Generic,
Cryptol.Eval.Prims,
Cryptol.Eval.Reference,
Cryptol.Eval.SBV,
Cryptol.Eval.Type,
Expand Down
34 changes: 17 additions & 17 deletions cryptol/REPL/Haskeline.hs
Original file line number Diff line number Diff line change
Expand Up @@ -48,38 +48,38 @@ import Prelude.Compat
crySession :: Maybe FilePath -> Bool -> REPL CommandExitCode
crySession mbBatch stopOnError =
do settings <- io (setHistoryFile (replSettings isBatch))
let act = runInputTBehavior behavior settings (withInterrupt loop)
let act = runInputTBehavior behavior settings (withInterrupt (loop 1))
if isBatch then asBatch act else act
where
(isBatch,behavior) = case mbBatch of
Nothing -> (False,defaultBehavior)
Just path -> (True,useFile path)

loop :: InputT REPL CommandExitCode
loop =
loop :: Int -> InputT REPL CommandExitCode
loop lineNum =
do ln <- getInputLines =<< MTL.lift getPrompt
case ln of
NoMoreLines -> return CommandOk
Interrupted
| isBatch && stopOnError -> return CommandError
| otherwise -> loop
NextLine line
| all isSpace line -> loop
| otherwise -> doCommand line

doCommand txt =
case parseCommand findCommandExact txt of
Nothing | isBatch && stopOnError -> return CommandError
| otherwise -> loop -- say somtething?
| otherwise -> loop lineNum
NextLine ls
| all (all isSpace) ls -> loop (lineNum + length ls)
| otherwise -> doCommand lineNum ls

doCommand lineNum txt =
case parseCommand findCommandExact (unlines txt) of
Nothing | isBatch && stopOnError -> return CommandError
| otherwise -> loop (lineNum + length txt) -- say somtething?
Just cmd -> join $ MTL.lift $
do status <- handleInterrupt (handleCtrlC CommandError) (runCommand cmd)
do status <- handleInterrupt (handleCtrlC CommandError) (runCommand lineNum mbBatch cmd)
case status of
CommandError | isBatch && stopOnError -> return (return status)
_ -> do goOn <- shouldContinue
return (if goOn then loop else return status)
return (if goOn then loop (lineNum + length txt) else return status)


data NextLine = NextLine String | NoMoreLines | Interrupted
data NextLine = NextLine [String] | NoMoreLines | Interrupted

getInputLines :: String -> InputT REPL NextLine
getInputLines = handleInterrupt (MTL.lift (handleCtrlC Interrupted)) . loop []
Expand All @@ -91,7 +91,7 @@ getInputLines = handleInterrupt (MTL.lift (handleCtrlC Interrupted)) . loop []
Nothing -> return NoMoreLines
Just l
| not (null l) && last l == '\\' -> loop (init l : ls) newPropmpt
| otherwise -> return $ NextLine $ unlines $ reverse $ l : ls
| otherwise -> return $ NextLine $ reverse $ l : ls

loadCryRC :: Cryptolrc -> REPL CommandExitCode
loadCryRC cryrc =
Expand Down Expand Up @@ -201,7 +201,7 @@ canDisplayColor = io (hSupportsANSI stdout)
cryptolCommand :: CompletionFunc REPL
cryptolCommand cursor@(l,r)
| ":" `isPrefixOf` l'
, Just (cmd,rest) <- splitCommand l' = case nub (findCommand cmd) of
, Just (_,cmd,rest) <- splitCommand l' = case nub (findCommand cmd) of

[c] | null rest && not (any isSpace l') -> do
return (l, cmdComp cmd c)
Expand Down
36 changes: 21 additions & 15 deletions src/Cryptol/Backend.hs
Original file line number Diff line number Diff line change
Expand Up @@ -35,31 +35,28 @@ import Data.Kind (Type)
import Data.Ratio ( (%), numerator, denominator )

import Cryptol.Backend.FloatHelpers (BF)
import Cryptol.Backend.Monad ( PPOpts(..), EvalError(..) )
import Cryptol.TypeCheck.AST(Name)
import Cryptol.Backend.Monad
( PPOpts(..), EvalError(..), CallStack, pushCallFrame )
import Cryptol.ModuleSystem.Name(Name)
import Cryptol.Parser.Position
import Cryptol.Utils.PP


invalidIndex :: Backend sym => sym -> Integer -> SEval sym a
invalidIndex sym = raiseError sym . InvalidIndex . Just
invalidIndex sym i = raiseError sym (InvalidIndex (Just i))

cryUserError :: Backend sym => sym -> String -> SEval sym a
cryUserError sym = raiseError sym . UserError
cryUserError sym msg = raiseError sym (UserError msg)

cryNoPrimError :: Backend sym => sym -> Name -> SEval sym a
cryNoPrimError sym = raiseError sym . NoPrim

cryNoPrimError sym nm = raiseError sym (NoPrim nm)

{-# INLINE sDelay #-}
-- | Delay the given evaluation computation, returning a thunk
-- which will run the computation when forced. Raise a loop
-- error if the resulting thunk is forced during its own evaluation.
sDelay :: Backend sym => sym -> Maybe String -> SEval sym a -> SEval sym (SEval sym a)
sDelay sym msg m =
let msg' = maybe "" ("while evaluating "++) msg
retry = raiseError sym (LoopError msg')
in sDelayFill sym m retry

sDelay :: Backend sym => sym -> SEval sym a -> SEval sym (SEval sym a)
sDelay sym m = sDelayFill sym m Nothing ""

-- | Representation of rational numbers.
-- Invariant: denominator is not 0
Expand Down Expand Up @@ -234,13 +231,23 @@ class MonadIO (SEval sym) => Backend sym where
-- which will run the computation when forced. Run the 'retry'
-- computation instead if the resulting thunk is forced during
-- its own evaluation.
sDelayFill :: sym -> SEval sym a -> SEval sym a -> SEval sym (SEval sym a)
sDelayFill :: sym -> SEval sym a -> Maybe (SEval sym a) -> String -> SEval sym (SEval sym a)

-- | Begin evaluating the given computation eagerly in a separate thread
-- and return a thunk which will await the completion of the given computation
-- when forced.
sSpark :: sym -> SEval sym a -> SEval sym (SEval sym a)

-- | Push a call frame on to the current call stack while evaluating the given action
sPushFrame :: sym -> Name -> Range -> SEval sym a -> SEval sym a
sPushFrame sym nm rng m = sModifyCallStack sym (pushCallFrame nm rng) m

-- | Apply the given function to the current call stack while evaluating the given action
sModifyCallStack :: sym -> (CallStack -> CallStack) -> SEval sym a -> SEval sym a

-- | Retrieve the current evaluation call stack
sGetCallStack :: sym -> SEval sym CallStack

-- | Merge the two given computations according to the predicate.
mergeEval ::
sym ->
Expand All @@ -257,7 +264,6 @@ class MonadIO (SEval sym) => Backend sym where
-- | Indiciate that an error condition exists
raiseError :: sym -> EvalError -> SEval sym a


-- ==== Pretty printing ====
-- | Pretty-print an individual bit
ppBit :: sym -> SBit sym -> Doc
Expand Down Expand Up @@ -674,7 +680,7 @@ class MonadIO (SEval sym) => Backend sym where
SInteger sym ->
SEval sym (SBit sym)

-- | Multiplicitive inverse in (Z n).
-- | Multiplicative inverse in (Z n).
-- PRECONDITION: the modulus is a prime
znRecip ::
sym ->
Expand Down
13 changes: 7 additions & 6 deletions src/Cryptol/Backend/Concrete.hs
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,12 @@ instance Backend Concrete where
type SFloat Concrete = FP.BF
type SEval Concrete = Eval

raiseError _ err = io (X.throwIO err)
raiseError _ err =
do stk <- getCallStack
io (X.throwIO (EvalErrorEx stk err))

assertSideCondition _ True _ = return ()
assertSideCondition _ False err = io (X.throwIO err)
assertSideCondition sym False err = raiseError sym err

wordLen _ (BV w _) = w
wordAsChar _ (BV _ x) = Just $! integerToChar x
Expand All @@ -157,9 +159,11 @@ instance Backend Concrete where
y <- my
f c x y

sDeclareHole _ = blackhole
sDeclareHole _ rng = blackhole rng
sDelayFill _ = delayFill
sSpark _ = evalSpark
sModifyCallStack _ f m = modifyCallStack f m
sGetCallStack _ = getCallStack

ppBit _ b | b = text "True"
| otherwise = text "False"
Expand Down Expand Up @@ -393,6 +397,3 @@ fpRoundMode sym w =
Right a -> pure a





Loading