-
Notifications
You must be signed in to change notification settings - Fork 13.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Get rid of the Scalar
and ScalarPair
variants of ConstValue
...
#55260
Changes from 1 commit
edf94c5
856eaed
fe4e950
04fc561
b11b3cb
3aecb0d
8d42376
847f5b9
e52644c
8246dd4
5620d68
fc6472c
336094f
b4ba332
dfc5d26
c50d77d
1d14a84
9fbce39
1f2fcee
e3bbe6d
6ff70da
7b526d8
9df63e9
a7a92e2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -684,24 +684,24 @@ impl<Tag: Copy, Extra: Default> Allocation<Tag, Extra> { | |
offset: Size, | ||
size: Size, | ||
) -> EvalResult<'tcx> { | ||
if self.relocations(hdl, offset, size)?.len() != 0 { | ||
if self.relocations(hdl, offset, size).len() != 0 { | ||
err!(ReadPointerAsBytes) | ||
} else { | ||
Ok(()) | ||
} | ||
} | ||
|
||
pub fn relocations( | ||
fn relocations( | ||
&self, | ||
hdl: impl HasDataLayout, | ||
offset: Size, | ||
size: Size, | ||
) -> EvalResult<'tcx, &[(Size, (Tag, AllocId))]> { | ||
) -> &[(Size, (Tag, AllocId))] { | ||
// We have to go back `pointer_size - 1` bytes, as that one would still overlap with | ||
// the beginning of this range. | ||
let start = offset.bytes().saturating_sub(hdl.pointer_size().bytes() - 1); | ||
let start = offset.bytes().saturating_sub(hdl.data_layout().pointer_size.bytes() - 1); | ||
let end = offset + size; // this does overflow checking | ||
Ok(self.relocations.range(Size::from_bytes(start)..end)) | ||
self.relocations.range(Size::from_bytes(start)..end) | ||
} | ||
|
||
pub fn get_bytes( | ||
|
@@ -736,22 +736,23 @@ impl<Tag: Copy, Extra: Default> Allocation<Tag, Extra> { | |
&self, | ||
hdl: impl HasDataLayout, | ||
offset: Size, | ||
size: Size, | ||
align: Align, | ||
) -> EvalResult<'tcx, Scalar<Tag>> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wait, why does (See, a doc comment would have been useful. ;) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this function is called There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm did the diff view fool me? Yes it did. I am still quite confused why this looks so different from what we do in memory.rs? |
||
let size = hdl.data_layout().pointer_size; | ||
let required_align = hdl.data_layout().pointer_align; | ||
self.check_align(offset, required_align)?; | ||
self.check_align(offset, align)?; | ||
self.check_bounds(offset, size, true)?; | ||
self.check_defined(offset, size)?; | ||
let bytes = self.bytes_ignoring_relocations_and_undef(offset, size); | ||
let offset = read_target_uint(hdl.data_layout().endian, &bytes).unwrap(); | ||
let offset = Size::from_bytes(offset as u64); | ||
if let Some(&(tag, alloc_id)) = self.relocations.get(&offset) { | ||
Ok(Pointer::new_with_tag(alloc_id, offset, tag).into()) | ||
} else { | ||
Ok(Scalar::Bits { | ||
bits: offset.bytes() as u128, | ||
let int = read_target_uint(hdl.data_layout().endian, &bytes).unwrap(); | ||
match self.relocations(hdl, offset, size) { | ||
&[(_, (tag, alloc_id))] if size == hdl.data_layout().pointer_size => { | ||
Ok(Pointer::new_with_tag(alloc_id, Size::from_bytes(int as u64), tag).into()) | ||
}, | ||
&[] => Ok(Scalar::Bits { | ||
bits: int, | ||
size: size.bytes() as u8, | ||
}) | ||
}), | ||
_ => err!(ReadPointerAsBytes), | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,7 @@ use rustc::mir; | |
use rustc::ty; | ||
use rustc::ty::layout::{self, Align, LayoutOf, TyLayout}; | ||
use rustc_data_structures::sync::Lrc; | ||
use syntax_pos::Span; | ||
|
||
use base; | ||
use common::{CodegenCx, C_undef, C_usize}; | ||
|
@@ -25,6 +26,7 @@ use glue; | |
use std::fmt; | ||
|
||
use super::{FunctionCx, LocalRef}; | ||
use super::constant::scalar_to_llvm; | ||
use super::place::PlaceRef; | ||
|
||
/// The representation of a Rust value. The enum variant is in fact | ||
|
@@ -77,6 +79,7 @@ impl OperandRef<'ll, 'tcx> { | |
} | ||
|
||
pub fn from_const(bx: &Builder<'a, 'll, 'tcx>, | ||
span: Span, | ||
val: &'tcx ty::Const<'tcx>) | ||
-> Result<OperandRef<'ll, 'tcx>, Lrc<ConstEvalErr<'tcx>>> { | ||
let layout = bx.cx.layout_of(val.ty); | ||
|
@@ -85,12 +88,65 @@ impl OperandRef<'ll, 'tcx> { | |
return Ok(OperandRef::new_zst(bx.cx, layout)); | ||
} | ||
|
||
match val.val { | ||
let econv = |err| ConstEvalErr { | ||
error: err, | ||
stacktrace: Vec::new(), | ||
span, | ||
}; | ||
|
||
let val = match val.val { | ||
ConstValue::Unevaluated(..) => bug!(), | ||
ConstValue::ByRef(_, alloc, offset) => { | ||
Ok(PlaceRef::from_const_alloc(bx, layout, alloc, offset).load(bx)) | ||
// FIXME: the first two arms are needed for simd_simple_float_intrinsic which reads | ||
// the constants back from llvm values. We can probably do better. | ||
match layout.abi { | ||
layout::Abi::Scalar(ref scalar) => { | ||
let x = alloc.read_scalar( | ||
bx.tcx(), offset, layout.size, layout.align, | ||
).map_err(econv)?; | ||
let llval = scalar_to_llvm( | ||
bx.cx, | ||
x, | ||
scalar, | ||
layout.immediate_llvm_type(bx.cx), | ||
); | ||
OperandValue::Immediate(llval) | ||
}, | ||
layout::Abi::ScalarPair(ref a_scalar, ref b_scalar) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a duplicate of... |
||
let a_size = a_scalar.value.size(bx.tcx()); | ||
let a = alloc.read_scalar( | ||
bx.tcx(), offset, a_size, a_scalar.value.align(bx.tcx()), | ||
).map_err(econv)?; | ||
let b_align = b_scalar.value.align(bx.tcx()); | ||
let b_offset = offset + a_size.abi_align(b_align); | ||
let b_size = b_scalar.value.size(bx.tcx()); | ||
let b = alloc.read_scalar( | ||
bx.tcx(), b_offset, b_size, b_align, | ||
).map_err(econv)?; | ||
let a_llval = scalar_to_llvm( | ||
bx.cx, | ||
a, | ||
a_scalar, | ||
layout.scalar_pair_element_llvm_type(bx.cx, 0, true), | ||
); | ||
let b_layout = layout.scalar_pair_element_llvm_type(bx.cx, 1, true); | ||
let b_llval = scalar_to_llvm( | ||
bx.cx, | ||
b, | ||
b_scalar, | ||
b_layout, | ||
); | ||
OperandValue::Pair(a_llval, b_llval) | ||
}, | ||
_ => return Ok(PlaceRef::from_const_alloc(bx, layout, alloc, offset).load(bx)), | ||
} | ||
}, | ||
} | ||
}; | ||
|
||
Ok(OperandRef { | ||
val, | ||
layout | ||
}) | ||
} | ||
|
||
/// Asserts that this operand refers to a scalar and returns | ||
|
@@ -383,7 +439,7 @@ impl FunctionCx<'a, 'll, 'tcx> { | |
mir::Operand::Constant(ref constant) => { | ||
let ty = self.monomorphize(&constant.ty); | ||
self.eval_mir_constant(bx, constant) | ||
.and_then(|c| OperandRef::from_const(bx, c)) | ||
.and_then(|c| OperandRef::from_const(bx, constant.span, c)) | ||
.unwrap_or_else(|err| { | ||
err.report_as_error( | ||
bx.tcx().at(constant.span), | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs a doc comment explaining exactly which checks are performed, and which not. (Internal relocations? Relocations on the edges?)
Also, if
memory.rs
uses this incopy
, it is required to provide an address stability guarantee on its return value.