-
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 enums #1991
MIR enums #1991
Conversation
35dfc90
to
d44eae1
Compare
d44eae1
to
14c7213
Compare
14c7213
to
b77ee63
Compare
@@ -742,6 +751,8 @@ regToSetup bak p eval shp rv = go shp rv | |||
refSV <- go refShp refRV | |||
lenSV <- go lenShp lenRV | |||
pure $ MS.SetupSlice $ MirSetupSliceRaw refSV lenSV | |||
go (EnumShape _ _ _ _ _) _ = | |||
error "Enums not currently supported in overrides" |
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.
See #1990 for the task of supporting enums in {crucible,crux}-mir-comp
.
-- | A shape for an enum type. Like 'StructShape', this is indexed by | ||
-- 'AnyType', so code that matches on 'EnumShape' may need to further match | ||
-- on the 'VariantShape's in order to bring additional type information into | ||
-- scope. | ||
EnumShape :: M.Ty | ||
-- ^ The overall enum type. | ||
-> [[M.Ty]] | ||
-- ^ The field types in each of the enum's variants. | ||
-> Assignment VariantShape ctx | ||
-- ^ The shapes of the enum type's variants. | ||
-> M.Ty | ||
-- ^ The discriminant type. | ||
-> TypeShape discrTp | ||
-- ^ The shape of the discriminant type. | ||
-> TypeShape AnyType |
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 a new TypeShape
constructor that is used extensively in this patch...
-- | The 'TypeShape' of an enum variant, which consists of some number of field | ||
-- types. | ||
-- | ||
-- This is indexed by a 'StructType', but that is simply an artifact of the | ||
-- particular way that @crucible-mir@ encodes enum types. Despite the use of | ||
-- 'StructType' as a type index, we only use 'VariantShape' for enums, not | ||
-- structs. | ||
data VariantShape (tp :: CrucibleType) where | ||
VariantShape :: Assignment FieldShape ctx | ||
-- ^ The shapes of the variant's field types. | ||
-> VariantShape (StructType ctx) |
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.
...as well as the related VariantShape
data type.
-- | A enum-related MIR 'SetupValue'. | ||
data MirSetupEnum where |
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 data type classifies the two ways that one can create an enum value (either via mir_enum_value
or mir_fresh_expanded_value
).
@@ -157,3 +229,137 @@ data MirSetupSlice | |||
makeLenses ''MIRCrucibleContext | |||
makeLenses ''MirAllocSpec | |||
makeLenses ''MirPointer | |||
|
|||
{- | |||
Note [Symbolic enums] |
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.
A large piece of documentation that I wrote about the approach to handling symbolic enum values.
[ "Expected struct type, received union:" | ||
, show nm | ||
] | ||
MS.SetupEnum enum_ -> |
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 implements turning a SetupEnum
into a value that Crucible can reason about. (It's quite involved, sadly—sorry.)
-- In order to match an enum value, we first check to see if the expected | ||
-- value is a specific enum variant or a symbolic enum... | ||
(MIRVal (EnumShape _ _ variantShps _ discrShp) | ||
(Crucible.AnyValue | ||
(Mir.RustEnumRepr discrTpr variantCtx) | ||
(Ctx.Empty | ||
Ctx.:> Crucible.RV actualDiscr | ||
Ctx.:> Crucible.RV variantAssn)), | ||
_, | ||
MS.SetupEnum enum_) |
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 implements matching one enum value against another.
-- Create a fresh symbolic enum value, as described in | ||
-- Note [Symboliic enums] in SAWScript.Crucible.MIR.Setup.Value. | ||
goEnum :: | ||
forall discrShp variantCtx. | ||
Text -> | ||
Mir.Adt -> | ||
TypeShape discrShp -> | ||
Ctx.Assignment VariantShape variantCtx -> | ||
CrucibleSetup MIR MirSetupEnum |
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 generates all of the symbolic variables used in a symbolic enum value.
constructing a struct value), and `mir_enum_value` (for constructing an enum | ||
value) commands in turn take a `MIRAdt` as an argument. | ||
|
||
#### Enums |
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 about enums.
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 good - just a few typos and minor comments
This adds basic support for enums in the MIR backend. In particular: * There is now a `mir_enum_value : MIRAdt -> String -> [MIRValue] -> MIRValue` function that constructs a value representing a specific enum variant, where the `String` indicates which variant to use. * The `mir_fresh_expanded_value` command can now create symbolic enum values. Implementation-wise, much of the complexity in this patch arises from the fact that MIR enums are represented with `VariantType`s at the Crucible level, which are a fair bit more involved than the `StructType`s used to power MIR structs. Some highlights of the implementation are: * There is now a new `EnumShape` constructor for `TypeShape`, which is in turn defined in terms of a new `VariantShape` data type that characterizes the shapes of all the fields in an enum variant. * There is a `MirSetupEnum` data type (exported by `SAWScript.Crucible.MIR.MethodSpecIR`) which categorizes the different forms of enum `MIRValue`s that one can construct. Currently, there is `MirSetupEnumVariant` (which is what `mir_enum_value` returns) and `MirSetupEnumSymbolic` (which is what `mir_fresh_expanded_value` returns when it creates a fresh enum value). * The implementation of symbolic enum values in particular is somewhat complicated. I have written `Note [Symbolic enums]` to go over the general approach and highlight some potential pitfalls in implementing them. * For now, there is no `crux-mir-comp` support for enums. We could conceivable add support, but there is not a pressing need to do so right now. I have opened #1990 as a reminder to do this later. This checks off one box in #1859.
b77ee63
to
658f6fd
Compare
This adds basic support for enums in the MIR backend. In particular:
mir_enum_value : MIRAdt -> String -> [MIRValue] -> MIRValue
function that constructs a value representing a specific enum variant, where theString
indicates which variant to use.mir_fresh_expanded_value
command can now create symbolic enum values.Implementation-wise, much of the complexity in this patch arises from the fact that MIR enums are represented with
VariantType
s at the Crucible level, which are a fair bit more involved than theStructType
s used to power MIR structs. Some highlights of the implementation are:EnumShape
constructor forTypeShape
, which is in turn defined in terms of a newVariantShape
data type that characterizes the shapes of all the fields in an enum variant.MirSetupEnum
data type (exported bySAWScript.Crucible.MIR.MethodSpecIR
) which categorizes the different forms of enumMIRValue
s that one can construct. Currently, there isMirSetupEnumVariant
(which is whatmir_enum_value
returns) andMirSetupEnumSymbolic
(which is whatmir_fresh_expanded_value
returns when it creates a fresh enum value).Note [Symbolic enums]
to go over the general approach and highlight some potential pitfalls in implementing them.crux-mir-comp
support for enums. We could conceivable add support, but there is not a pressing need to do so right now. I have openedcrux-mir-comp
: Support enums #1990 as a reminder to do this later.This checks off one box in #1859.