Skip to content

Commit

Permalink
feat(rust-mir): Support checked and unchecked binary operations
Browse files Browse the repository at this point in the history
  • Loading branch information
chorman0773 committed Dec 11, 2024
1 parent f96ec91 commit 57a6a53
Show file tree
Hide file tree
Showing 14 changed files with 579 additions and 51 deletions.
84 changes: 84 additions & 0 deletions frontend/rust/rust_mir_macro/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,26 @@ pub fn do_punct<I: Iterator<Item = TokenTree>>(
})
}

pub fn do_puncts<I: Iterator<Item = TokenTree>, K: IntoIterator<Item = &'static str>>(
tree: &mut PeekMoreIterator<I>,
kws: K,
) -> Result<(&'static str, Span)> {
let mut err = None;
for kw in kws {
match do_punct(tree, kw) {
Ok(span) => return Ok((kw, span)),
Err(e) => match err {
Some(er) => match alternation_combiner(Err(er), Err(e)) {
Err(e) => err = Some(e),
Ok(v) => match v {},
},
None => err = Some(e),
},
}
}

Err(err.expect("Required at least one keyword in `do_puncts`"))
}
pub fn do_literal<I: Iterator<Item = TokenTree>>(
tree: &mut PeekMoreIterator<I>,
) -> Result<Literal> {
Expand Down Expand Up @@ -1071,6 +1091,7 @@ pub fn do_expr<I: Iterator<Item = TokenTree>>(
do_expr_const_lit,
do_expr_ssa_var,
do_expr_read,
do_expr_binary,
do_expr_tuple,
do_expr_get_symbol,
do_expr_get_subobject,
Expand Down Expand Up @@ -1662,6 +1683,69 @@ pub fn do_expr_get_symbol<I: Iterator<Item = TokenTree>>(
})
}

pub fn do_expr_binary<I: Iterator<Item = TokenTree>>(
tokens: &mut PeekMoreIterator<I>,
dollar_crate: &TokenStream,
) -> Result<TokenStream> {
with_rewinder_accept_on_continue(tokens, |tree| {
let expr_ty = match do_keywords(tree, ["checked", "unchecked"]) {
Ok(("checked", _)) => "CheckedBinary",
Ok(("unchecked", _)) => "UncheckedBinary",
Ok(_) => unreachable!(),
Err(_) => "BinaryExpr",
};

let g = do_group(tree, Some(Delimiter::Parenthesis))?;
let span = g.span();

let mut inner_tree = g.stream().into_iter().peekmore();

let lhs = do_expr(&mut inner_tree, dollar_crate)?;

let op = match do_puncts(
&mut inner_tree,
["+", "-", "*", "/", "&", "|", "^", "<<", ">>"],
)? {
("+", span) => ("Add", span),
("-", span) => ("Sub", span),
("*", span) => ("Mul", span),
("&", span) => ("BitAnd", span),
("^", span) => ("BitXor", span),
("|", span) => ("BitOr", span),
("<<", span) => ("LeftShift", span),
(">>", span) => ("RightShift", span),
_ => unreachable!(),
};

let rhs = do_expr(&mut inner_tree, dollar_crate)?;
let mut op_ts = TokenStream::new();
write_crate_path(
&mut op_ts,
op.1,
dollar_crate,
["sema", "mir", "BinaryOp", op.0],
);

let mut inner = TokenStream::new();
inner.extend(write_spanned(op_ts, op.1, false, dollar_crate));
inner.extend(punct(","));
inner.extend(write_spanned(lhs, span, true, dollar_crate));
inner.extend(punct(","));
inner.extend(write_spanned(rhs, span, true, dollar_crate));

let mut ts = TokenStream::new();

write_crate_path(
&mut ts,
span,
dollar_crate,
["sema", "mir", "MirExpr", expr_ty],
);
ts.extend(group(inner, Delimiter::Parenthesis));
Ok(ts)
})
}

pub fn do_terminator<I: Iterator<Item = TokenTree>>(
tokens: &mut PeekMoreIterator<I>,
dollar_crate: &TokenStream,
Expand Down
2 changes: 2 additions & 0 deletions frontend/rust/src/irgen/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,8 @@ pub fn visit_expr<V: ExprVisitor>(mut visitor: V, expr: &mir::MirExpr, defs: &De
}
mir::MirExpr::InlineConst(_) => todo!("inline const"),
mir::MirExpr::ConstBool(_) => todo!("bool"),
mir::MirExpr::CheckedBinary(op, lhs, rhs) => todo!(),
mir::MirExpr::UncheckedBinary(op, lhs, rhs) => todo!(),
}
}

Expand Down
7 changes: 6 additions & 1 deletion frontend/rust/src/sema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2279,6 +2279,7 @@ impl Definitions {
fields,
}))
}
cx::ConstExpr::FloatConst(fty, val) => Ok(cx::ConstExpr::FloatConst(*fty, *val)),
}
}

Expand All @@ -2293,7 +2294,7 @@ impl Definitions {
unreachable!("Unexpanded Complex Expressions")
}
cx::ConstExpr::StringConst(val) => Ok(val),
val => panic!("{val} is not a u64"),
val => panic!("{val} is not a string"),
}
}

Expand All @@ -2316,6 +2317,7 @@ impl Definitions {
relevant_item: at_item,
hints: vec![],
}),
cx::ConstExpr::FloatConst(fty, val) => panic!("{val}_{fty} is not a u64"),
cx::ConstExpr::BoolConst(val) => panic!("{val} is not a u64"),
cx::ConstExpr::Const(defid, _) => panic!("{defid} is not a u64"),
cx::ConstExpr::Constructor(ctor) => panic!("{ctor} is not a u64"),
Expand Down Expand Up @@ -2347,6 +2349,9 @@ impl Definitions {
"\"{}\" is not a struct, union, or enum type",
val.escape_default()
),
cx::ConstExpr::FloatConst(fty, val) => {
panic!("{val}_{fty} is not a struct, union, or enum type")
}
}
}

Expand Down
17 changes: 14 additions & 3 deletions frontend/rust/src/sema/cx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use super::{
hir::HirExpr,
intrin::IntrinsicDef,
mir::MirFunctionBody,
ty::{FieldName, IntType},
ty::{FieldName, FloatType, IntType, ScalarNiches},
DefId, Spanned,
};

Expand All @@ -19,6 +19,7 @@ pub enum ConstExpr {
HirVal(Box<HirExpr>),
MirVal(Box<MirFunctionBody>),
IntConst(IntType, u128),
FloatConst(FloatType, u128),
Const(DefId, GenericArgs),
Param(ParamId),
Constructor(ConstExprConstructor),
Expand All @@ -32,6 +33,7 @@ impl core::fmt::Display for ConstExpr {
ConstExpr::HirVal(val) => f.write_fmt(format_args!("const {{ {} }}", val)),
ConstExpr::MirVal(val) => f.write_fmt(format_args!("/* mir const */")),
ConstExpr::IntConst(ity, val) => f.write_fmt(format_args!("{}_{}", val, ity)),
ConstExpr::FloatConst(fty, val) => f.write_fmt(format_args!("{}_{}", val, fty)),
ConstExpr::Const(def, generics) => f.write_fmt(format_args!("")),
ConstExpr::Param(par) => par.fmt(f),
ConstExpr::Constructor(ctor) => ctor.fmt(f),
Expand All @@ -47,6 +49,7 @@ impl ConstExpr {
Self::HirVal(val) => panic!("Expand HIR Vals before substituting"),
Self::MirVal(body) => Self::MirVal(Box::new(body.substitute_generics(args))),
Self::IntConst(ity, val) => Self::IntConst(*ity, *val),
Self::FloatConst(fty, val) => Self::FloatConst(*fty, *val),
Self::BoolConst(v) => Self::BoolConst(*v),
Self::StringConst(v) => Self::StringConst(*v),
Self::Const(defid, generics) => Self::Const(*defid, generics.substitute_generics(args)),
Expand Down Expand Up @@ -101,10 +104,18 @@ impl core::fmt::Display for ConstExprConstructor {
}
}

#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub enum ValidityError {
RequiresInit,
ScalarValidityError(ScalarNiches, u128),
RequiresValidPtr,
}

#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub enum UbType {
OutOfBoundsAccess,
ValidityCheckFailed,
OutOfBoundsAccess { offset: usize, len: usize },
ValidityCheckFailed(ValidityError),
SymbolicPointerTransmute,
}

#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
Expand Down
Loading

0 comments on commit 57a6a53

Please sign in to comment.