@@ -1003,12 +1003,11 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
1003
1003
lvalue : Lvalue < ' tcx > ,
1004
1004
) -> EvalResult < ' tcx , Lvalue < ' tcx > > {
1005
1005
let new_lvalue = match lvalue {
1006
- Lvalue :: Local { frame, local, field } => {
1006
+ Lvalue :: Local { frame, local } => {
1007
1007
// -1 since we don't store the return value
1008
1008
match self . stack [ frame] . locals [ local. index ( ) - 1 ] {
1009
1009
None => return Err ( EvalError :: DeadLocal ) ,
1010
1010
Some ( Value :: ByRef ( ptr) ) => {
1011
- assert ! ( field. is_none( ) ) ;
1012
1011
Lvalue :: from_ptr ( ptr)
1013
1012
} ,
1014
1013
Some ( val) => {
@@ -1018,12 +1017,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
1018
1017
let ptr = self . alloc_ptr_with_substs ( ty, substs) ?;
1019
1018
self . stack [ frame] . locals [ local. index ( ) - 1 ] = Some ( Value :: ByRef ( ptr) ) ; // it stays live
1020
1019
self . write_value_to_ptr ( val, PrimVal :: Ptr ( ptr) , ty) ?;
1021
- let lval = Lvalue :: from_ptr ( ptr) ;
1022
- if let Some ( ( field, field_ty) ) = field {
1023
- self . lvalue_field ( lval, field, ty, field_ty) ?
1024
- } else {
1025
- lval
1026
- }
1020
+ Lvalue :: from_ptr ( ptr)
1027
1021
}
1028
1022
}
1029
1023
}
@@ -1110,11 +1104,11 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
1110
1104
self . write_value_to_ptr ( src_val, ptr, dest_ty)
1111
1105
}
1112
1106
1113
- Lvalue :: Local { frame, local, field } => {
1114
- let dest = self . stack [ frame] . get_local ( local, field . map ( | ( i , _ ) | i ) ) ?;
1107
+ Lvalue :: Local { frame, local } => {
1108
+ let dest = self . stack [ frame] . get_local ( local) ?;
1115
1109
self . write_value_possibly_by_val (
1116
1110
src_val,
1117
- |this, val| this. stack [ frame] . set_local ( local, field . map ( | ( i , _ ) | i ) , val) ,
1111
+ |this, val| this. stack [ frame] . set_local ( local, val) ,
1118
1112
dest,
1119
1113
dest_ty,
1120
1114
)
@@ -1353,7 +1347,12 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
1353
1347
I128 => 16 ,
1354
1348
Is => self . memory . pointer_size ( ) ,
1355
1349
} ;
1356
- PrimVal :: from_i128 ( self . memory . read_int ( ptr, size) ?)
1350
+ // if we cast a ptr to an isize, reading it back into a primval shouldn't panic
1351
+ // Due to read_ptr ignoring the sign, we need to jump around some hoops
1352
+ match self . memory . read_int ( ptr, size) {
1353
+ Err ( EvalError :: ReadPointerAsBytes ) if size == self . memory . pointer_size ( ) => self . memory . read_ptr ( ptr) ?,
1354
+ other => PrimVal :: from_i128 ( other?) ,
1355
+ }
1357
1356
}
1358
1357
1359
1358
ty:: TyUint ( uint_ty) => {
@@ -1366,7 +1365,12 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
1366
1365
U128 => 16 ,
1367
1366
Us => self . memory . pointer_size ( ) ,
1368
1367
} ;
1369
- PrimVal :: from_u128 ( self . memory . read_uint ( ptr, size) ?)
1368
+ if size == self . memory . pointer_size ( ) {
1369
+ // if we cast a ptr to an usize, reading it back into a primval shouldn't panic
1370
+ self . memory . read_ptr ( ptr) ?
1371
+ } else {
1372
+ PrimVal :: from_u128 ( self . memory . read_uint ( ptr, size) ?)
1373
+ }
1370
1374
}
1371
1375
1372
1376
ty:: TyFloat ( FloatTy :: F32 ) => PrimVal :: from_f32 ( self . memory . read_f32 ( ptr) ?) ,
@@ -1518,19 +1522,16 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
1518
1522
1519
1523
pub ( super ) fn dump_local ( & self , lvalue : Lvalue < ' tcx > ) {
1520
1524
// Debug output
1521
- if let Lvalue :: Local { frame, local, field } = lvalue {
1525
+ if let Lvalue :: Local { frame, local } = lvalue {
1522
1526
let mut allocs = Vec :: new ( ) ;
1523
1527
let mut msg = format ! ( "{:?}" , local) ;
1524
- if let Some ( ( field, _) ) = field {
1525
- write ! ( msg, ".{}" , field) . unwrap ( ) ;
1526
- }
1527
1528
let last_frame = self . stack . len ( ) - 1 ;
1528
1529
if frame != last_frame {
1529
1530
write ! ( msg, " ({} frames up)" , last_frame - frame) . unwrap ( ) ;
1530
1531
}
1531
1532
write ! ( msg, ":" ) . unwrap ( ) ;
1532
1533
1533
- match self . stack [ frame] . get_local ( local, field . map ( | ( i , _ ) | i ) ) {
1534
+ match self . stack [ frame] . get_local ( local) {
1534
1535
Err ( EvalError :: DeadLocal ) => {
1535
1536
write ! ( msg, " is dead" ) . unwrap ( ) ;
1536
1537
}
@@ -1575,14 +1576,13 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
1575
1576
& mut self ,
1576
1577
frame : usize ,
1577
1578
local : mir:: Local ,
1578
- field : Option < usize > ,
1579
1579
f : F ,
1580
1580
) -> EvalResult < ' tcx >
1581
1581
where F : FnOnce ( & mut Self , Value ) -> EvalResult < ' tcx , Value > ,
1582
1582
{
1583
- let val = self . stack [ frame] . get_local ( local, field ) ?;
1583
+ let val = self . stack [ frame] . get_local ( local) ?;
1584
1584
let new_val = f ( self , val) ?;
1585
- self . stack [ frame] . set_local ( local, field , new_val) ?;
1585
+ self . stack [ frame] . set_local ( local, new_val) ?;
1586
1586
// FIXME(solson): Run this when setting to Undef? (See previous version of this code.)
1587
1587
// if let Value::ByRef(ptr) = self.stack[frame].get_local(local) {
1588
1588
// self.memory.deallocate(ptr)?;
@@ -1598,59 +1598,20 @@ impl<'tcx> Frame<'tcx> {
1598
1598
_ => false ,
1599
1599
}
1600
1600
}
1601
- pub fn get_local ( & self , local : mir:: Local , field : Option < usize > ) -> EvalResult < ' tcx , Value > {
1601
+ pub fn get_local ( & self , local : mir:: Local ) -> EvalResult < ' tcx , Value > {
1602
1602
// Subtract 1 because we don't store a value for the ReturnPointer, the local with index 0.
1603
- if let Some ( field) = field {
1604
- Ok ( match self . locals [ local. index ( ) - 1 ] {
1605
- None => return Err ( EvalError :: DeadLocal ) ,
1606
- Some ( Value :: ByRef ( _) ) => bug ! ( "can't have lvalue fields for ByRef" ) ,
1607
- Some ( val @ Value :: ByVal ( _) ) => {
1608
- assert_eq ! ( field, 0 ) ;
1609
- val
1610
- } ,
1611
- Some ( Value :: ByValPair ( a, b) ) => {
1612
- match field {
1613
- 0 => Value :: ByVal ( a) ,
1614
- 1 => Value :: ByVal ( b) ,
1615
- _ => bug ! ( "ByValPair has only two fields, tried to access {}" , field) ,
1616
- }
1617
- } ,
1618
- } )
1619
- } else {
1620
- self . locals [ local. index ( ) - 1 ] . ok_or ( EvalError :: DeadLocal )
1621
- }
1603
+ self . locals [ local. index ( ) - 1 ] . ok_or ( EvalError :: DeadLocal )
1622
1604
}
1623
1605
1624
- fn set_local ( & mut self , local : mir:: Local , field : Option < usize > , value : Value ) -> EvalResult < ' tcx > {
1606
+ fn set_local ( & mut self , local : mir:: Local , value : Value ) -> EvalResult < ' tcx > {
1625
1607
// Subtract 1 because we don't store a value for the ReturnPointer, the local with index 0.
1626
- if let Some ( field) = field {
1627
- match self . locals [ local. index ( ) - 1 ] {
1628
- None => return Err ( EvalError :: DeadLocal ) ,
1629
- Some ( Value :: ByRef ( _) ) => bug ! ( "can't have lvalue fields for ByRef" ) ,
1630
- Some ( Value :: ByVal ( _) ) => {
1631
- assert_eq ! ( field, 0 ) ;
1632
- self . set_local ( local, None , value) ?;
1633
- } ,
1634
- Some ( Value :: ByValPair ( a, b) ) => {
1635
- let prim = match value {
1636
- Value :: ByRef ( _) => bug ! ( "can't set ValPair field to ByRef" ) ,
1637
- Value :: ByVal ( val) => val,
1638
- Value :: ByValPair ( _, _) => bug ! ( "can't set ValPair field to ValPair" ) ,
1639
- } ;
1640
- match field {
1641
- 0 => self . set_local ( local, None , Value :: ByValPair ( prim, b) ) ?,
1642
- 1 => self . set_local ( local, None , Value :: ByValPair ( a, prim) ) ?,
1643
- _ => bug ! ( "ByValPair has only two fields, tried to access {}" , field) ,
1644
- }
1645
- } ,
1646
- }
1647
- } else {
1648
- match self . locals [ local. index ( ) - 1 ] {
1649
- None => return Err ( EvalError :: DeadLocal ) ,
1650
- Some ( ref mut local) => { * local = value; }
1608
+ match self . locals [ local. index ( ) - 1 ] {
1609
+ None => Err ( EvalError :: DeadLocal ) ,
1610
+ Some ( ref mut local) => {
1611
+ * local = value;
1612
+ Ok ( ( ) )
1651
1613
}
1652
1614
}
1653
- return Ok ( ( ) ) ;
1654
1615
}
1655
1616
1656
1617
pub fn storage_live ( & mut self , local : mir:: Local ) -> EvalResult < ' tcx , Option < Value > > {
0 commit comments