Reimplement sum type switching.

This commit is contained in:
Scott Olson 2016-03-13 06:30:28 -06:00
parent 80d12601ff
commit 6d37e7fc29
3 changed files with 36 additions and 26 deletions

View File

@ -174,6 +174,16 @@ impl<'a, 'tcx: 'a> Interpreter<'a, 'tcx> {
}
}
Switch { ref discr, ref targets, .. } => {
let (adt_ptr, adt_repr) = try!(self.eval_lvalue(discr));
let discr_repr = match adt_repr {
Repr::Sum { ref discr, .. } => discr,
_ => panic!("attmpted to switch on non-sum type"),
};
let discr_val = try!(self.memory.read_primval(adt_ptr, &discr_repr));
current_block = targets[discr_val.to_int() as usize];
}
// Call { ref func, ref args, ref destination, .. } => {
// use rustc::middle::cstore::CrateStore;
// let ptr = destination.as_ref().map(|&(ref lv, _)| self.lvalue_to_ptr(lv));
@ -203,16 +213,6 @@ impl<'a, 'tcx: 'a> Interpreter<'a, 'tcx> {
// }
// }
// Switch { ref discr, ref targets, .. } => {
// let discr_val = self.read_lvalue(discr);
// if let Value::Adt { variant, .. } = discr_val {
// current_block = targets[variant];
// } else {
// panic!("Switch on non-Adt value: {:?}", discr_val);
// }
// }
Drop { target, .. } => {
// TODO: Handle destructors and dynamic drop.
current_block = target;

View File

@ -22,6 +22,16 @@ impl PrimVal {
_ => panic!("attempted to make integer primval from non-integer repr"),
}
}
pub fn to_int(self) -> i64 {
match self {
PrimVal::I8(n) => n as i64,
PrimVal::I16(n) => n as i64,
PrimVal::I32(n) => n as i64,
PrimVal::I64(n) => n,
_ => panic!("attempted to make integer from non-integer primval"),
}
}
}
pub fn binary_op(bin_op: mir::BinOp, left: PrimVal, right: PrimVal) -> PrimVal {

View File

@ -30,20 +30,20 @@ fn return_some() -> Option<i64> {
Some(42)
}
// #[miri_run]
// fn match_opt_none() -> i64 {
// let x = None,
// match x {
// Some(data) => data,
// None => 42,
// }
// }
#[miri_run]
fn match_opt_none() -> i8 {
let x = None::<i32>;
match x {
Some(_) => 10,
None => 20,
}
}
// #[miri_run]
// fn match_opt_some() -> i64 {
// let x = Some(13);
// match x {
// Some(data) => data,
// None => 42,
// }
// }
#[miri_run]
fn match_opt_some() -> i8 {
let x = Some(13);
match x {
Some(_) => 10,
None => 20,
}
}