diff --git a/ykpack/src/lib.rs b/ykpack/src/lib.rs index 89e9a50ab..9e315e784 100644 --- a/ykpack/src/lib.rs +++ b/ykpack/src/lib.rs @@ -41,7 +41,8 @@ pub use types::*; #[cfg(test)] mod tests { use super::{ - BasicBlock, Decoder, DefId, Encoder, Mir, Pack, Place, Rvalue, Statement, Terminator, + BasicBlock, Decoder, DefId, Encoder, Mir, Operand, Pack, Place, PlaceBase, Rvalue, + Statement, Terminator, }; use fallible_iterator::{self, FallibleIterator}; use std::io::{Cursor, Seek, SeekFrom}; @@ -137,10 +138,13 @@ mod tests { fn test_text_dump() { let stmts_t1_b0 = vec![ Statement::Nop, - Statement::Assign(Place::Local(42), Rvalue::Place(Place::Local(43))), Statement::Assign( - Place::Local(44), - Rvalue::Phi(vec![Place::Local(100), Place::Local(200)]), + Place::Base(PlaceBase::Local(42)), + Rvalue::Use(Operand::Place(Place::Base(PlaceBase::Local(43)))), + ), + Statement::Assign( + Place::Base(PlaceBase::Local(44)), + Rvalue::Use(Operand::Place(Place::Base(PlaceBase::Local(300)))), ), ]; let term_t1_b0 = Terminator::Abort; @@ -168,21 +172,21 @@ mod tests { let got_lines = got.split("\n"); let expect = "[Begin TIR for item1]\n\ - DefId(1, 2): - bb0: - Nop - Assign(Local(42), Place(Local(43))) - Assign(Local(44), Phi([Local(100), Local(200)])) - term: Abort - - bb1: - Unimplemented - term: Goto { target_bb: 50 } - - [End TIR for item1] - [Begin TIR for item2] - DefId(3, 4): - [End TIR for item2]\n"; + DefId(1, 2): + bb0: + Nop + Assign(Base(Local(42)), Use(Place(Base(Local(43))))) + Assign(Base(Local(44)), Use(Place(Base(Local(300))))) + term: Abort + + bb1: + Unimplemented + term: Goto { target_bb: 50 } + + [End TIR for item1] + [Begin TIR for item2] + DefId(3, 4): + [End TIR for item2]\n"; let expect_lines = expect.split("\n"); diff --git a/ykpack/src/types.rs b/ykpack/src/types.rs index 2b05d48dd..5be4d3b84 100644 --- a/ykpack/src/types.rs +++ b/ykpack/src/types.rs @@ -10,12 +10,17 @@ //! Types for the Yorick intermediate language. use serde::{Deserialize, Serialize}; -use std::fmt::{self, Display}; +use std::{ + fmt::{self, Display}, + marker::PhantomData, +}; pub type CrateHash = u64; pub type DefIndex = u32; pub type BasicBlockIndex = u32; pub type LocalIndex = u32; +pub type VariantIndex = u32; +pub type PromotedIndex = u32; /// A mirror of the compiler's notion of a "definition ID". #[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] @@ -93,7 +98,8 @@ impl Display for BasicBlock { pub enum Statement { Nop, Assign(Place, Rvalue), - Unimplemented, // FIXME + SetDiscriminant(Place, VariantIndex), + Unimplemented, } impl Display for Statement { @@ -102,19 +108,112 @@ impl Display for Statement { } } +/// A place for storing things. #[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] pub enum Place { + Base(PlaceBase), + Projection(PlaceProjection), +} + +/// The "base" of a place projection. +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] +pub enum PlaceBase { Local(LocalIndex), - Unimplemented, // FIXME + Static(DefId), + Promoted(PromotedIndex), } +/// A projection (deref, index, field access, ...). #[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] -pub enum Rvalue { +pub struct PlaceProjection { + pub base: Box, + pub elem: ProjectionElem, +} + +/// Describes a projection operation upon a projection base. +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] +pub enum ProjectionElem { + Unimplemented(PhantomData), // FIXME +} + +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] +pub enum Operand { + /// In MIR this is either Move or Copy. Place(Place), - Phi(Vec), + Unimplemented, // FIXME constants +} + +/// Borrow descriptions. +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] +pub enum BorrowKind { + Shared, + Shallow, + Unique, + Mut, // FIXME two_phase borrow. +} + +/// Things that can appear on the right-hand side of an assignment. +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] +pub enum Rvalue { + Use(Operand), + Repeat(Operand, u64), + Ref(BorrowKind, Place), // We do not store the region. + Len(Place), + BinaryOp(BinOp, Operand, Operand), + CheckedBinaryOp(BinOp, Operand, Operand), + NullaryOp(NullOp), + UnaryOp(UnOp, Operand), + Discriminant(Place), + Aggregate(AggregateKind, Vec), Unimplemented, // FIXME } +/// Kinds of aggregate types. +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] +pub enum AggregateKind { + Array, + Tuple, + Closure(DefId), + Generator(DefId), + Unimplemented, +} + +/// Binary operations. +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] +pub enum BinOp { + Add, + Sub, + Mul, + Div, + Rem, + BitXor, + BitAnd, + BitOr, + Shl, + Shr, + Eq, + Lt, + Le, + Ne, + Ge, + Gt, + Offset, +} + +// Operations with no arguments. +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] +pub enum NullOp { + SizeOf, + Box, +} + +// Unary operations. +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] +pub enum UnOp { + Not, + Neg, +} + /// A call target. #[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] pub enum CallOperand {