Skip to content

Commit b36a831

Browse files
committed
Turn PrimVal into an enum including Undefined.
This is step 1 of a refactoring to fix rust-lang#95. The `Undefined` variant is so far unused and the old `bits` and `relocation` fields are emulated with two new temporary methods. There should be no functional change due to this commit.
1 parent 9674e50 commit b36a831

File tree

7 files changed

+132
-120
lines changed

7 files changed

+132
-120
lines changed

src/cast.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
2020
F32 => self.cast_float(val.to_f32() as f64, dest_ty),
2121
F64 => self.cast_float(val.to_f64(), dest_ty),
2222

23-
I8 | I16 | I32 | I64 => self.cast_signed_int(val.bits as i64, dest_ty),
23+
I8 | I16 | I32 | I64 => self.cast_signed_int(val.bits() as i64, dest_ty),
2424

25-
Bool | Char | U8 | U16 | U32 | U64 => self.cast_int(val.bits, dest_ty, false),
25+
Bool | Char | U8 | U16 | U32 | U64 => self.cast_int(val.bits(), dest_ty, false),
2626

2727
FnPtr | Ptr => self.cast_ptr(val.to_ptr(), dest_ty),
2828
}
@@ -39,15 +39,15 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
3939
TyBool if v == 1 => Ok(PrimVal::from_bool(true)),
4040
TyBool => Err(EvalError::InvalidBool),
4141

42-
TyInt(IntTy::I8) => Ok(PrimVal::new(v as i64 as i8 as u64)),
43-
TyInt(IntTy::I16) => Ok(PrimVal::new(v as i64 as i16 as u64)),
44-
TyInt(IntTy::I32) => Ok(PrimVal::new(v as i64 as i32 as u64)),
45-
TyInt(IntTy::I64) => Ok(PrimVal::new(v as i64 as i64 as u64)),
42+
TyInt(IntTy::I8) => Ok(PrimVal::Bytes(v as i64 as i8 as u64)),
43+
TyInt(IntTy::I16) => Ok(PrimVal::Bytes(v as i64 as i16 as u64)),
44+
TyInt(IntTy::I32) => Ok(PrimVal::Bytes(v as i64 as i32 as u64)),
45+
TyInt(IntTy::I64) => Ok(PrimVal::Bytes(v as i64 as i64 as u64)),
4646

47-
TyUint(UintTy::U8) => Ok(PrimVal::new(v as u8 as u64)),
48-
TyUint(UintTy::U16) => Ok(PrimVal::new(v as u16 as u64)),
49-
TyUint(UintTy::U32) => Ok(PrimVal::new(v as u32 as u64)),
50-
TyUint(UintTy::U64) => Ok(PrimVal::new(v)),
47+
TyUint(UintTy::U8) => Ok(PrimVal::Bytes(v as u8 as u64)),
48+
TyUint(UintTy::U16) => Ok(PrimVal::Bytes(v as u16 as u64)),
49+
TyUint(UintTy::U32) => Ok(PrimVal::Bytes(v as u32 as u64)),
50+
TyUint(UintTy::U64) => Ok(PrimVal::Bytes(v)),
5151

5252
TyInt(IntTy::Is) => {
5353
let int_ty = self.tcx.sess.target.int_type;
@@ -66,10 +66,10 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
6666
TyFloat(FloatTy::F32) if negative => Ok(PrimVal::from_f32(v as i64 as f32)),
6767
TyFloat(FloatTy::F32) => Ok(PrimVal::from_f32(v as f32)),
6868

69-
TyChar if v as u8 as u64 == v => Ok(PrimVal::new(v)),
69+
TyChar if v as u8 as u64 == v => Ok(PrimVal::Bytes(v)),
7070
TyChar => Err(EvalError::InvalidChar(v)),
7171

72-
TyRawPtr(_) => Ok(PrimVal::from_ptr(Pointer::from_int(v))),
72+
TyRawPtr(_) => Ok(PrimVal::Pointer(Pointer::from_int(v))),
7373

7474
_ => Err(EvalError::Unimplemented(format!("int to {:?} cast", ty))),
7575
}
@@ -94,7 +94,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
9494
use rustc::ty::TypeVariants::*;
9595
match ty.sty {
9696
TyRef(..) | TyRawPtr(_) | TyFnPtr(_) | TyInt(_) | TyUint(_) =>
97-
Ok(PrimVal::from_ptr(ptr)),
97+
Ok(PrimVal::Pointer(ptr)),
9898
_ => Err(EvalError::Unimplemented(format!("ptr to {:?} cast", ty))),
9999
}
100100
}

src/eval_context.rs

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -172,15 +172,15 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
172172
let ptr = self.memory.allocate(s.len() as u64, 1)?;
173173
self.memory.write_bytes(ptr, s.as_bytes())?;
174174
self.memory.freeze(ptr.alloc_id)?;
175-
Ok(Value::ByValPair(PrimVal::from_ptr(ptr), PrimVal::from_uint(s.len() as u64)))
175+
Ok(Value::ByValPair(PrimVal::Pointer(ptr), PrimVal::from_uint(s.len() as u64)))
176176
}
177177

178178
pub(super) fn const_to_value(&mut self, const_val: &ConstVal) -> EvalResult<'tcx, Value> {
179179
use rustc::middle::const_val::ConstVal::*;
180180
use rustc_const_math::ConstFloat;
181181

182182
let primval = match *const_val {
183-
Integral(const_int) => PrimVal::new(const_int.to_u64_unchecked()),
183+
Integral(const_int) => PrimVal::Bytes(const_int.to_u64_unchecked()),
184184

185185
Float(ConstFloat::F32(f)) => PrimVal::from_f32(f),
186186
Float(ConstFloat::F64(f)) => PrimVal::from_f64(f),
@@ -196,7 +196,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
196196
let ptr = self.memory.allocate(bs.len() as u64, 1)?;
197197
self.memory.write_bytes(ptr, bs)?;
198198
self.memory.freeze(ptr.alloc_id)?;
199-
PrimVal::from_ptr(ptr)
199+
PrimVal::Pointer(ptr)
200200
}
201201

202202
Struct(_) => unimplemented!(),
@@ -315,14 +315,14 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
315315
.expect("global should have been cached (freeze)");
316316
match global_value.data.expect("global should have been initialized") {
317317
Value::ByRef(ptr) => self.memory.freeze(ptr.alloc_id)?,
318-
Value::ByVal(val) => if let Some(alloc_id) = val.relocation {
318+
Value::ByVal(val) => if let Some(alloc_id) = val.relocation() {
319319
self.memory.freeze(alloc_id)?;
320320
},
321321
Value::ByValPair(a, b) => {
322-
if let Some(alloc_id) = a.relocation {
322+
if let Some(alloc_id) = a.relocation() {
323323
self.memory.freeze(alloc_id)?;
324324
}
325-
if let Some(alloc_id) = b.relocation {
325+
if let Some(alloc_id) = b.relocation() {
326326
self.memory.freeze(alloc_id)?;
327327
}
328328
},
@@ -500,7 +500,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
500500
assert_eq!(operands.len(), 0);
501501
if let mir::AggregateKind::Adt(adt_def, variant, _, _) = *kind {
502502
let n = adt_def.variants[variant].disr_val.to_u64_unchecked();
503-
self.write_primval(dest, PrimVal::new(n), dest_ty)?;
503+
self.write_primval(dest, PrimVal::Bytes(n), dest_ty)?;
504504
} else {
505505
bug!("tried to assign {:?} to Layout::CEnum", kind);
506506
}
@@ -563,12 +563,12 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
563563
Ref(_, _, ref lvalue) => {
564564
let src = self.eval_lvalue(lvalue)?;
565565
let (raw_ptr, extra) = self.force_allocation(src)?.to_ptr_and_extra();
566-
let ptr = PrimVal::from_ptr(raw_ptr);
566+
let ptr = PrimVal::Pointer(raw_ptr);
567567

568568
let val = match extra {
569569
LvalueExtra::None => Value::ByVal(ptr),
570570
LvalueExtra::Length(len) => Value::ByValPair(ptr, PrimVal::from_uint(len)),
571-
LvalueExtra::Vtable(vtable) => Value::ByValPair(ptr, PrimVal::from_ptr(vtable)),
571+
LvalueExtra::Vtable(vtable) => Value::ByValPair(ptr, PrimVal::Pointer(vtable)),
572572
LvalueExtra::DowncastVariant(..) =>
573573
bug!("attempted to take a reference to an enum downcast lvalue"),
574574
};
@@ -578,7 +578,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
578578

579579
Box(ty) => {
580580
let ptr = self.alloc_ptr(ty)?;
581-
self.write_primval(dest, PrimVal::from_ptr(ptr), dest_ty)?;
581+
self.write_primval(dest, PrimVal::Pointer(ptr), dest_ty)?;
582582
}
583583

584584
Cast(kind, ref operand, cast_ty) => {
@@ -617,7 +617,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
617617
ty::TyFnDef(def_id, substs, fn_ty) => {
618618
let fn_ty = self.tcx.erase_regions(&fn_ty);
619619
let fn_ptr = self.memory.create_fn_ptr(self.tcx,def_id, substs, fn_ty);
620-
self.write_value(Value::ByVal(PrimVal::from_ptr(fn_ptr)), dest, dest_ty)?;
620+
self.write_value(Value::ByVal(PrimVal::Pointer(fn_ptr)), dest, dest_ty)?;
621621
},
622622
ref other => bug!("reify fn pointer on {:?}", other),
623623
},
@@ -629,7 +629,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
629629
let (def_id, substs, _, _) = self.memory.get_fn(ptr.alloc_id)?;
630630
let unsafe_fn_ty = self.tcx.erase_regions(&unsafe_fn_ty);
631631
let fn_ptr = self.memory.create_fn_ptr(self.tcx, def_id, substs, unsafe_fn_ty);
632-
self.write_value(Value::ByVal(PrimVal::from_ptr(fn_ptr)), dest, dest_ty)?;
632+
self.write_value(Value::ByVal(PrimVal::Pointer(fn_ptr)), dest, dest_ty)?;
633633
},
634634
ref other => bug!("fn to unsafe fn cast on {:?}", other),
635635
},
@@ -1093,10 +1093,10 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
10931093

10941094
fn ensure_valid_value(&self, val: PrimVal, ty: Ty<'tcx>) -> EvalResult<'tcx, ()> {
10951095
match ty.sty {
1096-
ty::TyBool if val.bits > 1 => Err(EvalError::InvalidBool),
1096+
ty::TyBool if val.bits() > 1 => Err(EvalError::InvalidBool),
10971097

1098-
ty::TyChar if ::std::char::from_u32(val.bits as u32).is_none()
1099-
=> Err(EvalError::InvalidChar(val.bits as u32 as u64)),
1098+
ty::TyChar if ::std::char::from_u32(val.bits() as u32).is_none()
1099+
=> Err(EvalError::InvalidChar(val.bits() as u32 as u64)),
11001100

11011101
_ => Ok(()),
11021102
}
@@ -1150,23 +1150,23 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
11501150
ty::TyFloat(FloatTy::F32) => PrimVal::from_f32(self.memory.read_f32(ptr)?),
11511151
ty::TyFloat(FloatTy::F64) => PrimVal::from_f64(self.memory.read_f64(ptr)?),
11521152

1153-
ty::TyFnPtr(_) => self.memory.read_ptr(ptr).map(PrimVal::from_ptr)?,
1153+
ty::TyFnPtr(_) => self.memory.read_ptr(ptr).map(PrimVal::Pointer)?,
11541154
ty::TyBox(ty) |
11551155
ty::TyRef(_, ty::TypeAndMut { ty, .. }) |
11561156
ty::TyRawPtr(ty::TypeAndMut { ty, .. }) => {
11571157
let p = self.memory.read_ptr(ptr)?;
11581158
if self.type_is_sized(ty) {
1159-
PrimVal::from_ptr(p)
1159+
PrimVal::Pointer(p)
11601160
} else {
11611161
trace!("reading fat pointer extra of type {}", ty);
11621162
let extra = ptr.offset(self.memory.pointer_size());
11631163
let extra = match self.tcx.struct_tail(ty).sty {
1164-
ty::TyDynamic(..) => PrimVal::from_ptr(self.memory.read_ptr(extra)?),
1164+
ty::TyDynamic(..) => PrimVal::Pointer(self.memory.read_ptr(extra)?),
11651165
ty::TySlice(..) |
11661166
ty::TyStr => PrimVal::from_uint(self.memory.read_usize(extra)?),
11671167
_ => bug!("unsized primval ptr read from {:?}", ty),
11681168
};
1169-
return Ok(Some(Value::ByValPair(PrimVal::from_ptr(p), extra)));
1169+
return Ok(Some(Value::ByValPair(PrimVal::Pointer(p), extra)));
11701170
}
11711171
}
11721172

@@ -1225,7 +1225,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
12251225
(&ty::TyArray(_, length), &ty::TySlice(_)) => {
12261226
let ptr = src.read_ptr(&self.memory)?;
12271227
let len = PrimVal::from_uint(length as u64);
1228-
let ptr = PrimVal::from_ptr(ptr);
1228+
let ptr = PrimVal::Pointer(ptr);
12291229
self.write_value(Value::ByValPair(ptr, len), dest, dest_ty)?;
12301230
}
12311231
(&ty::TyDynamic(..), &ty::TyDynamic(..)) => {
@@ -1239,8 +1239,8 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
12391239
let trait_ref = self.tcx.erase_regions(&trait_ref);
12401240
let vtable = self.get_vtable(trait_ref)?;
12411241
let ptr = src.read_ptr(&self.memory)?;
1242-
let ptr = PrimVal::from_ptr(ptr);
1243-
let extra = PrimVal::from_ptr(vtable);
1242+
let ptr = PrimVal::Pointer(ptr);
1243+
let extra = PrimVal::Pointer(vtable);
12441244
self.write_value(Value::ByValPair(ptr, extra), dest, dest_ty)?;
12451245
},
12461246

@@ -1301,12 +1301,12 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
13011301
}
13021302
Value::ByVal(val) => {
13031303
trace!("frame[{}] {:?}: {:?}", frame, local, val);
1304-
if let Some(alloc_id) = val.relocation { allocs.push(alloc_id); }
1304+
if let Some(alloc_id) = val.relocation() { allocs.push(alloc_id); }
13051305
}
13061306
Value::ByValPair(val1, val2) => {
13071307
trace!("frame[{}] {:?}: ({:?}, {:?})", frame, local, val1, val2);
1308-
if let Some(alloc_id) = val1.relocation { allocs.push(alloc_id); }
1309-
if let Some(alloc_id) = val2.relocation { allocs.push(alloc_id); }
1308+
if let Some(alloc_id) = val1.relocation() { allocs.push(alloc_id); }
1309+
if let Some(alloc_id) = val2.relocation() { allocs.push(alloc_id); }
13101310
}
13111311
}
13121312
}

src/memory.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -587,18 +587,18 @@ impl<'a, 'tcx> Memory<'a, 'tcx> {
587587
val: PrimVal,
588588
kind: PrimValKind,
589589
) -> EvalResult<'tcx, ()> {
590-
if let Some(alloc_id) = val.relocation {
591-
return self.write_ptr(dest, Pointer::new(alloc_id, val.bits));
590+
if let Some(alloc_id) = val.relocation() {
591+
return self.write_ptr(dest, Pointer::new(alloc_id, val.bits()));
592592
}
593593

594594
use value::PrimValKind::*;
595595
let (size, bits) = match kind {
596-
I8 | U8 | Bool => (1, val.bits as u8 as u64),
597-
I16 | U16 => (2, val.bits as u16 as u64),
598-
I32 | U32 | F32 | Char => (4, val.bits as u32 as u64),
599-
I64 | U64 | F64 => (8, val.bits),
596+
I8 | U8 | Bool => (1, val.bits() as u8 as u64),
597+
I16 | U16 => (2, val.bits() as u16 as u64),
598+
I32 | U32 | F32 | Char => (4, val.bits() as u32 as u64),
599+
I64 | U64 | F64 => (8, val.bits()),
600600
// int -> ptr transmutes are handled here
601-
FnPtr | Ptr => return self.write_usize(dest, val.bits),
601+
FnPtr | Ptr => return self.write_usize(dest, val.bits()),
602602
};
603603

604604
self.write_uint(dest, bits, size)

src/operator.rs

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
6666
macro_rules! overflow {
6767
($op:ident, $l:expr, $r:expr) => ({
6868
let (val, overflowed) = $l.$op($r);
69-
let primval = PrimVal::new(val as u64);
69+
let primval = PrimVal::Bytes(val as u64);
7070
Ok((primval, overflowed))
7171
})
7272
}
@@ -112,7 +112,7 @@ macro_rules! float_arithmetic {
112112
let l = $from_bits($l);
113113
let r = $from_bits($r);
114114
let bits = $to_bits(l $float_op r);
115-
PrimVal::new(bits)
115+
PrimVal::Bytes(bits)
116116
})
117117
}
118118

@@ -148,7 +148,7 @@ pub fn binary_op<'tcx>(
148148
return Ok((unrelated_ptr_ops(bin_op, left_ptr, right_ptr)?, false));
149149
}
150150

151-
let (l, r) = (left.bits, right.bits);
151+
let (l, r) = (left.bits(), right.bits());
152152

153153
// These ops can have an RHS with a different numeric type.
154154
if bin_op == Shl || bin_op == Shr {
@@ -165,7 +165,7 @@ pub fn binary_op<'tcx>(
165165

166166
// Cast to `u32` because `overflowing_sh{l,r}` only take `u32`, then apply the bitmask
167167
// to ensure it's within the valid shift value range.
168-
let r = (right.bits as u32) & (type_bits - 1);
168+
let r = (right.bits() as u32) & (type_bits - 1);
169169

170170
return match bin_op {
171171
Shl => int_shift!(left_kind, overflowing_shl, l, r),
@@ -213,9 +213,9 @@ pub fn binary_op<'tcx>(
213213
(Gt, _) => PrimVal::from_bool(l > r),
214214
(Ge, _) => PrimVal::from_bool(l >= r),
215215

216-
(BitOr, _) => PrimVal::new(l | r),
217-
(BitAnd, _) => PrimVal::new(l & r),
218-
(BitXor, _) => PrimVal::new(l ^ r),
216+
(BitOr, _) => PrimVal::Bytes(l | r),
217+
(BitAnd, _) => PrimVal::Bytes(l & r),
218+
(BitXor, _) => PrimVal::Bytes(l ^ r),
219219

220220
(Add, k) if k.is_int() => return int_arithmetic!(k, overflowing_add, l, r),
221221
(Sub, k) if k.is_int() => return int_arithmetic!(k, overflowing_sub, l, r),
@@ -254,31 +254,31 @@ pub fn unary_op<'tcx>(
254254
use value::PrimValKind::*;
255255

256256
let bits = match (un_op, val_kind) {
257-
(Not, Bool) => !bits_to_bool(val.bits) as u64,
257+
(Not, Bool) => !bits_to_bool(val.bits()) as u64,
258258

259-
(Not, U8) => !(val.bits as u8) as u64,
260-
(Not, U16) => !(val.bits as u16) as u64,
261-
(Not, U32) => !(val.bits as u32) as u64,
262-
(Not, U64) => !val.bits,
259+
(Not, U8) => !(val.bits() as u8) as u64,
260+
(Not, U16) => !(val.bits() as u16) as u64,
261+
(Not, U32) => !(val.bits() as u32) as u64,
262+
(Not, U64) => !val.bits(),
263263

264-
(Not, I8) => !(val.bits as i8) as u64,
265-
(Not, I16) => !(val.bits as i16) as u64,
266-
(Not, I32) => !(val.bits as i32) as u64,
267-
(Not, I64) => !(val.bits as i64) as u64,
264+
(Not, I8) => !(val.bits() as i8) as u64,
265+
(Not, I16) => !(val.bits() as i16) as u64,
266+
(Not, I32) => !(val.bits() as i32) as u64,
267+
(Not, I64) => !(val.bits() as i64) as u64,
268268

269-
(Neg, I8) => -(val.bits as i8) as u64,
270-
(Neg, I16) => -(val.bits as i16) as u64,
271-
(Neg, I32) => -(val.bits as i32) as u64,
272-
(Neg, I64) => -(val.bits as i64) as u64,
269+
(Neg, I8) => -(val.bits() as i8) as u64,
270+
(Neg, I16) => -(val.bits() as i16) as u64,
271+
(Neg, I32) => -(val.bits() as i32) as u64,
272+
(Neg, I64) => -(val.bits() as i64) as u64,
273273

274-
(Neg, F32) => f32_to_bits(-bits_to_f32(val.bits)),
275-
(Neg, F64) => f64_to_bits(-bits_to_f64(val.bits)),
274+
(Neg, F32) => f32_to_bits(-bits_to_f32(val.bits())),
275+
(Neg, F64) => f64_to_bits(-bits_to_f64(val.bits())),
276276

277277
_ => {
278278
let msg = format!("unimplemented unary op: {:?}, {:?}", un_op, val);
279279
return Err(EvalError::Unimplemented(msg));
280280
}
281281
};
282282

283-
Ok(PrimVal::new(bits))
283+
Ok(PrimVal::Bytes(bits))
284284
}

0 commit comments

Comments
 (0)