Skip to content

Commit 57caee6

Browse files
committed
Split out crucible-mir from crux-mir
For the most part, most code was moved wholesale from `crux-mir` with only minor changes (I removed redundant imports to more easily determine which library dependencies could be dropped in `crucible-mir`). The most unusual change was creating a new `Mir.ParseTranslate` module in `crucible-mir`, which contains the `parseMIR` and `translateMIR` functions previously defined in `Mir.Generate` (now a `crux-mir` module that only exports `generateMIR`). Fixes #1065.
1 parent a946dc9 commit 57caee6

25 files changed

+234
-184
lines changed

cabal.project

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ packages:
99
crucible-go/
1010
crucible-jvm/
1111
crucible-llvm/
12+
crucible-mir/
1213
crucible-wasm/
1314
crucible-syntax/
1415
crucible-concurrency/

crucible-mir/CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# 0.1
2+
3+
* TODO: Describe API changes here

crucible-mir/LICENSE

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
Copyright (c) 2017-2023 Galois, Inc.
2+
3+
All rights reserved.
4+
5+
Redistribution and use in source and binary forms, with or without
6+
modification, are permitted provided that the following conditions are met:
7+
8+
* Redistributions of source code must retain the above copyright
9+
notice, this list of conditions and the following disclaimer.
10+
11+
* Redistributions in binary form must reproduce the above
12+
copyright notice, this list of conditions and the following
13+
disclaimer in the documentation and/or other materials provided
14+
with the distribution.
15+
16+
* Neither the name of the authors nor the names of other
17+
contributors may be used to endorse or promote products derived
18+
from this software without specific prior written permission.
19+
20+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

crucible-mir/README.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# crucible-mir
2+
3+
This package implements a MIR frontend for Crucible. This exports all of the
4+
code that is useful across multiple projects that make use of MIR, such as
5+
[`crux-mir`](https://github.com/GaloisInc/crucible/blob/master/crux-mir) and
6+
[`crux-mir-comp`](https://github.com/GaloisInc/saw-script/blob/master/crux-mir-comp).

crucible-mir/crucible-mir.cabal

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: crucible-mir
2+
version: 0.1
3+
-- synopsis:
4+
-- description:
5+
homepage: https://github.com/GaloisInc/crucible/blob/master/crucible-mir/README.md
6+
license: BSD3
7+
license-file: LICENSE
8+
author: Joshua Gancher,
9+
Rob Dockins,
10+
Andrey Chudnov,
11+
Stephanie Weirich,
12+
Stuart Pernsteiner
13+
maintainer: [email protected]
14+
copyright: 2017-2023 Galois, Inc.
15+
category: Web
16+
build-type: Simple
17+
cabal-version: 2.0
18+
extra-source-files: README.md
19+
20+
library
21+
default-language: Haskell2010
22+
build-depends: base >= 4.11 && < 5,
23+
aeson < 2.1,
24+
bv-sized,
25+
bytestring,
26+
prettyprinter >= 1.7.0,
27+
text,
28+
unordered-containers,
29+
crucible,
30+
parameterized-utils >= 1.0.8,
31+
containers,
32+
lens,
33+
vector,
34+
mtl,
35+
regex-compat,
36+
regex-base,
37+
transformers,
38+
what4,
39+
scientific >= 0.3,
40+
template-haskell
41+
42+
hs-source-dirs: src
43+
exposed-modules: Mir.JSON
44+
Mir.Generator
45+
Mir.Mir
46+
Mir.GenericOps
47+
Mir.ParseTranslate
48+
Mir.Pass
49+
Mir.Pass.AllocateEnum
50+
Mir.PP
51+
Mir.DefId
52+
Mir.FancyMuxTree
53+
Mir.Intrinsics
54+
Mir.TransTy
55+
Mir.Trans
56+
Mir.TransCustom
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

crux-mir/src/Mir/JSON.hs renamed to crucible-mir/src/Mir/JSON.hs

+4-8
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,17 @@ import qualified Data.Aeson.Types as Aeson
1515
import qualified Data.Map.Strict as Map
1616
import qualified Data.Scientific as Scientific
1717

18-
import Data.Word (Word64, Word8)
19-
import Data.Bits
18+
import Data.Word (Word8)
2019
import qualified Data.ByteString as BS
2120
import qualified Data.Char as Char
2221
import Data.Text (Text, unpack)
2322
import qualified Data.Text as T
2423
import qualified Data.Text.Read as T
25-
import Data.List
2624
import qualified Data.Vector as V
27-
import Control.Lens((^.),(&),(.~))
25+
import Control.Lens((^.))
2826

2927
#if MIN_VERSION_aeson(2,0,0)
30-
import Data.Aeson.Key (Key)
28+
import qualified Data.Aeson.Key as K (Key)
3129
import qualified Data.Aeson.KeyMap as KM
3230
#else
3331
import qualified Data.HashMap.Lazy as HML
@@ -36,8 +34,6 @@ import qualified Data.HashMap.Lazy as HML
3634
import Mir.DefId
3735
import Mir.Mir
3836

39-
import Debug.Trace
40-
4137
--------------------------------------------------------------------------------------
4238
-- | FromJSON instances
4339

@@ -550,7 +546,7 @@ instance FromJSON Static where
550546

551547
-- TODO: When the ecosystem widely uses aeson-2.0.0.0 or later, remove this CPP.
552548
#if MIN_VERSION_aeson(2,0,0)
553-
lookupKM :: Key -> KM.KeyMap Value -> Maybe Value
549+
lookupKM :: K.Key -> KM.KeyMap Value -> Maybe Value
554550
lookupKM = KM.lookup
555551
#else
556552
lookupKM :: Text -> HML.HashMap Text Value -> Maybe Value
File renamed without changes.

crux-mir/src/Mir/PP.hs renamed to crucible-mir/src/Mir/PP.hs

+2-2
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ instance Pretty MirBody where
143143
pretty (MirBody mvs mbs _) =
144144
vcat (map pretty_temp mvs ++
145145
map pretty mbs)
146-
146+
147147
instance Pretty BasicBlock where
148148
pretty (BasicBlock info dat) =
149149
vcat [
@@ -296,7 +296,7 @@ instance Pretty FloatLit where
296296

297297
instance Pretty Substs where
298298
pretty (Substs b) = langle <> hcat (punctuate comma (map pretty b)) <> rangle
299-
299+
300300
instance Pretty ConstVal where
301301
pretty (ConstFloat i) = pretty i
302302
pretty (ConstInt i) = pretty i
+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
{-# LANGUAGE LambdaCase #-}
2+
{-# LANGUAGE ImplicitParams #-}
3+
-----------------------------------------------------------------------
4+
-- |
5+
-- Module : Mir.ParseTranslate
6+
-- Description : Produce MIR AST and translate to Crucible
7+
-- Copyright : (c) Galois, Inc 2018
8+
-- License : BSD3
9+
-- Stability : provisional
10+
--
11+
-- Entry points for parsing and translating the MIR AST into Crucible.
12+
-----------------------------------------------------------------------
13+
14+
15+
module Mir.ParseTranslate (parseMIR, translateMIR) where
16+
17+
import Control.Lens hiding((<.>))
18+
import Control.Monad (when)
19+
20+
import qualified Data.Aeson as J
21+
import qualified Data.ByteString.Lazy as B
22+
import qualified Data.Map as M
23+
24+
import GHC.Stack
25+
26+
import Prettyprinter (Pretty(..))
27+
28+
import qualified Lang.Crucible.FunctionHandle as C
29+
30+
31+
import Mir.Mir (Collection(..), namedTys)
32+
import Mir.JSON ()
33+
import Mir.GenericOps (uninternTys)
34+
import Mir.Pass(rewriteCollection)
35+
import Mir.Generator(RustModule(..),CollectionState(..), collection)
36+
import Mir.Trans(transCollection)
37+
import qualified Mir.TransCustom as Mir (customOps)
38+
39+
import Debug.Trace
40+
41+
42+
parseMIR :: (HasCallStack, ?debug::Int) =>
43+
FilePath
44+
-> B.ByteString
45+
-> IO Collection
46+
parseMIR path f = do
47+
let c = (J.eitherDecode f) :: Either String Collection
48+
case c of
49+
Left msg -> fail $ "JSON Decoding of " ++ path ++ " failed: " ++ msg
50+
Right col -> do
51+
when (?debug > 5) $ do
52+
traceM "--------------------------------------------------------------"
53+
traceM $ "Loaded module: " ++ path
54+
traceM $ show (pretty col)
55+
traceM "--------------------------------------------------------------"
56+
return $ uninternMir col
57+
58+
uninternMir :: Collection -> Collection
59+
uninternMir col = uninternTys unintern (col { _namedTys = mempty })
60+
where
61+
-- NB: knot-tying is happening here. Some values in `tyMap` depend on
62+
-- other values. This should be okay: the original `rustc::ty::Ty`s are
63+
-- acyclic, so the entries in `tyMap` should be too.
64+
tyMap = fmap (uninternTys unintern) (col^.namedTys)
65+
unintern name = case M.lookup name tyMap of
66+
Nothing -> error $ "missing " ++ show name ++ " in type map"
67+
Just ty -> ty
68+
69+
70+
-- | Translate a MIR collection to Crucible
71+
translateMIR :: (HasCallStack, ?debug::Int, ?assertFalseOnError::Bool, ?printCrucible::Bool)
72+
=> CollectionState -> Collection -> C.HandleAllocator -> IO RustModule
73+
translateMIR lib col halloc =
74+
let ?customOps = Mir.customOps in
75+
let col0 = let ?mirLib = lib^.collection in rewriteCollection col
76+
in let ?libCS = lib in transCollection col0 halloc

crux-mir/src/Mir/Pass.hs renamed to crucible-mir/src/Mir/Pass.hs

+3-10
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,18 @@ module Mir.Pass (
1010
) where
1111

1212

13-
import Control.Monad.State.Lazy
14-
import Data.List
1513
import Control.Lens hiding (op,(|>))
16-
import qualified Data.Text as T
17-
import Data.Map(Map)
1814
import qualified Data.Map.Strict as Map
19-
import qualified Data.Maybe as Maybe
2015

2116
import GHC.Stack
2217

2318
import Mir.Mir
2419
import Mir.DefId
2520
import Mir.PP(fmt)
26-
import Mir.GenericOps
2721

2822
import Mir.Pass.AllocateEnum ( passAllocateEnum )
2923

3024
import Debug.Trace
31-
import GHC.Stack
3225

3326
type Pass = (?debug::Int, ?mirLib::Collection, HasCallStack) => Collection -> Collection
3427

@@ -41,7 +34,7 @@ x |> f = f x
4134
rewriteCollection :: Pass
4235
rewriteCollection col =
4336
col
44-
|> passAllocateEnum
37+
|> passAllocateEnum
4538

4639
--------------------------------------------------------------------------------------
4740

@@ -52,7 +45,7 @@ passId = id
5245

5346
passTrace :: String -> Pass
5447
passTrace str col =
55-
if (?debug > 5) then
48+
if (?debug > 5) then
5649
((trace $ "*********MIR collection " ++ str ++ "*******\n"
5750
++ fmt col ++ "\n****************************")
5851
col)
@@ -65,6 +58,6 @@ toCollectionPass f col = col { _functions = (fromList (f (Map.elems (col^.functi
6558
fromList :: [Fn] -> Map.Map DefId Fn
6659
fromList = foldr (\fn m -> Map.insert (fn^.fname) fn m) Map.empty
6760

68-
--------------------------------------------------------------------------------------
61+
--------------------------------------------------------------------------------------
6962

7063

crux-mir/src/Mir/Pass/AllocateEnum.hs renamed to crucible-mir/src/Mir/Pass/AllocateEnum.hs

+3-8
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,16 @@
1515
module Mir.Pass.AllocateEnum
1616
( passAllocateEnum
1717
) where
18-
18+
1919
import Control.Lens hiding (op)
20-
import Control.Monad.State.Lazy
2120
import qualified Data.Text as T
22-
import qualified Data.Map.Strict as Map
2321
import Data.List
2422

2523
import Mir.DefId
2624
import Mir.Mir
27-
import Mir.GenericOps
2825

2926
import GHC.Stack
3027

31-
import Debug.Trace
32-
3328
{-
3429
3530
Look for sequences of statements of the form
@@ -63,7 +58,7 @@ data FieldUpdate = FieldUpdate { adtLvalue :: Lvalue,
6358

6459
lookupAdt :: (?col :: Collection) => DefId -> Maybe Adt
6560
lookupAdt defid = find (\adt -> _adtname adt == defid) (?col^.adts)
66-
61+
6762

6863
isAdtFieldUpdate :: Statement -> Maybe FieldUpdate
6964
isAdtFieldUpdate (Assign (LProj (LProj lv (Downcast j)) (PField i ty)) (Use rhs) pos) =
@@ -91,7 +86,7 @@ makeAggregate updates (lv, k, adt) =
9186
pos = case updates of
9287
u:_ -> upos u
9388
[] -> "internal"
94-
89+
9590

9691
findAllocEnum :: (?col :: Collection) => [Statement] -> Maybe ( Statement, [Statement] )
9792
findAllocEnum ss = f ss [] where
File renamed without changes.

0 commit comments

Comments
 (0)