-
Notifications
You must be signed in to change notification settings - Fork 62
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
mir_slice_value
and mir_slice_range_value
#1948
Conversation
-- | ||
-- To make it easier to recurse on the 'TypeShape's for the slice's | ||
-- reference and length types, we provide the 'sliceShapeParts' function. | ||
SliceShape :: M.Ty |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note the new addition of SliceShape
, which is distinct from TupleShape
.
-- | A slice-related MIR 'SetupValue'. | ||
data MirSetupSlice | ||
= MirSetupSliceRaw (MS.SetupValue MIR) (MS.SetupValue MIR) | ||
-- ^ A \"raw\" slice constructed directly from a pointer and a length. | ||
-- Currently, this is only used by @crucible-mir-comp@. SAWScript offers no | ||
-- way to use this, although we may consider doing so in the future. | ||
| MirSetupSlice (MS.SetupValue MIR) | ||
-- ^ A slice of a reference to a contiguous sequence 'SetupValue'. | ||
-- Currently, this only supports references to arrays. | ||
| MirSetupSliceRange (MS.SetupValue MIR) Int Int | ||
-- ^ A slice of a reference to a contiguous sequence 'SetupValue', where the | ||
-- slice only covers the range specified by the given start and end values | ||
-- (the first and second 'Int', respectively). Currently, this only | ||
-- supports references to arrays, and it only supports concrete ranges. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An important new data type that classifies all of the different ways one can construct slice values in SAW/crucible-mir-comp
.
MirSetupSliceRaw{} -> | ||
panic "typeOfSetupValue" ["MirSetupSliceRaw not yet implemented"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MirSetupSliceRaw
is only used in crucible-mir-comp
at the moment, so I didn't bother implemented support for it in SAW.
MirSetupSlice arrRef -> do | ||
SetupSliceFromArray _elemTpr sliceShp refVal len <- | ||
resolveSetupSliceFromArray bak arrRef | ||
lenVal <- usizeBvLit sym len | ||
pure $ MIRVal sliceShp (Ctx.Empty Ctx.:> RV refVal Ctx.:> RV lenVal) | ||
MirSetupSliceRange arrRef start end -> do | ||
unless (start <= end) $ | ||
fail $ "slice index starts at " ++ show start | ||
++ " but ends at " ++ show end | ||
SetupSliceFromArray elemTpr sliceShp refVal0 len <- | ||
resolveSetupSliceFromArray bak arrRef | ||
unless (end < len) $ | ||
fail $ "range end index " ++ show end | ||
++ " out of range for slice of length " ++ show len | ||
startBV <- usizeBvLit sym start | ||
refVal1 <- Mir.mirRef_offsetIO bak iTypes elemTpr refVal0 startBV | ||
lenVal <- usizeBvLit sym $ end - start | ||
pure $ MIRVal sliceShp (Ctx.Empty Ctx.:> RV refVal1 Ctx.:> RV lenVal) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is where the magic happens, such as interfacing with the crucible-mir
memory model and checking the start/end values of slice ranges.
@@ -2648,6 +2650,77 @@ construct compound values: | |||
* `mir_tuple_value : [MIRValue] -> MIRValue` construct a tuple with the given | |||
list of values as elements. | |||
|
|||
### MIR slices |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Documentation
Thinking about this some more, there are a couple of unresolved questions in this PR:
|
Thinking about this some more:
|
ab0b82e
to
9fa9f7f
Compare
I've implemented the ideas in #1948 (comment), so this is now ready for review. |
I've realized that |
In general, it might be nice to have a way to cast |
Ah, I like that idea better. A casting function would also be handy if you wanted to take an immutable slice of a |
I've opened #1954 to track this idea. This idea can be implemented separately and applies to more things than just slices, so I don't think we need to hold up this PR while we wait for that. |
9fa9f7f
to
091a94e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks generally good, except for some confusion around half-open vs inclusive ranges in mir_slice_range_value
. It should use half-open for consistency with Rust, where arr[start..end]
is much more common than the inclusive version arr[start..=end]
.
I'm not entirely clear on why we need a separate SliceShape
when it's a strict subset of StructShape
, but it doesn't seem like it was much trouble to introduce this distinction.
This adds `mir_slice_value` and `mir_slice_range_value` functions to the MIR backend, which allow writing specifications involving slice arguments. Currently, only slices to array references are supported, although we may expand the scope of these commands in the future. Some interesting parts of the implementation: 1. The `TypeShape` for slices is _ever_-so-slightly different from the `TypeShape` for tuples (`TupleShape`), so I added a new `SliceShape` `TypeShape` to tell them apart. 2. There is a `MirSetupSliceRaw` constructor that is _only_ used for `crucible-mir-comp` purposes at the moment. In the future, we may want to expose a SAWScript command that uses this to allow users to directly construct a slice from a pointer and a length. 3. `mir_alloc` now explicitly disallows allocating slice references, so passing `mir_slice` or `mir_str` as an argument will throw an error. This checks off one box in #1859.
091a94e
to
813b844
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If all the half-open range stuff is fixed, then I think this is good to merge.
This adds
mir_slice_value
andmir_slice_range_value
functions to the MIR backend, which allow writing specifications involving slice arguments. Currently, only slices to array references are supported, although we may expand the scope of these commands in the future.Some interesting parts of the implementation:
The
TypeShape
for slices is ever-so-slightly different from theTypeShape
for tuples (TupleShape
), so I added a newSliceShape
TypeShape
to tell them apart.There is a
MirSetupSliceRaw
constructor that is only used forcrucible-mir-comp
purposes at the moment. In the future, we may want to expose a SAWScript command that uses this to allow users to directly construct a slice from a pointer and a length.mir_alloc
now explicitly disallows allocating slice references, so passingmir_slice
ormir_str
as an argument will throw an error.This checks off one box in #1859.