Generalized base::unsize_thin_ptr
This commit is contained in:
parent
034f69753b
commit
78dd95f4c7
7 changed files with 61 additions and 41 deletions
|
@ -208,7 +208,7 @@ pub fn unsized_info<'tcx, Cx: CodegenMethods<'tcx>>(
|
||||||
let vtable_ptr = cx.layout_of(cx.tcx().mk_mut_ptr(target))
|
let vtable_ptr = cx.layout_of(cx.tcx().mk_mut_ptr(target))
|
||||||
.field(cx, abi::FAT_PTR_EXTRA);
|
.field(cx, abi::FAT_PTR_EXTRA);
|
||||||
cx.static_ptrcast(meth::get_vtable(cx, source, data.principal()),
|
cx.static_ptrcast(meth::get_vtable(cx, source, data.principal()),
|
||||||
cx.backend_type(vtable_ptr))
|
cx.backend_type(&vtable_ptr))
|
||||||
}
|
}
|
||||||
_ => bug!("unsized_info: invalid unsizing {:?} -> {:?}",
|
_ => bug!("unsized_info: invalid unsizing {:?} -> {:?}",
|
||||||
source,
|
source,
|
||||||
|
@ -217,12 +217,12 @@ pub fn unsized_info<'tcx, Cx: CodegenMethods<'tcx>>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Coerce `src` to `dst_ty`. `src_ty` must be a thin pointer.
|
/// Coerce `src` to `dst_ty`. `src_ty` must be a thin pointer.
|
||||||
pub fn unsize_thin_ptr(
|
pub fn unsize_thin_ptr<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
|
||||||
bx: &Builder<'a, 'll, 'tcx>,
|
bx: &Bx,
|
||||||
src: &'ll Value,
|
src: Bx::Value,
|
||||||
src_ty: Ty<'tcx>,
|
src_ty: Ty<'tcx>,
|
||||||
dst_ty: Ty<'tcx>
|
dst_ty: Ty<'tcx>
|
||||||
) -> (&'ll Value, &'ll Value) {
|
) -> (Bx::Value, Bx::Value) {
|
||||||
debug!("unsize_thin_ptr: {:?} => {:?}", src_ty, dst_ty);
|
debug!("unsize_thin_ptr: {:?} => {:?}", src_ty, dst_ty);
|
||||||
match (&src_ty.sty, &dst_ty.sty) {
|
match (&src_ty.sty, &dst_ty.sty) {
|
||||||
(&ty::Ref(_, a, _),
|
(&ty::Ref(_, a, _),
|
||||||
|
@ -232,13 +232,13 @@ pub fn unsize_thin_ptr(
|
||||||
(&ty::RawPtr(ty::TypeAndMut { ty: a, .. }),
|
(&ty::RawPtr(ty::TypeAndMut { ty: a, .. }),
|
||||||
&ty::RawPtr(ty::TypeAndMut { ty: b, .. })) => {
|
&ty::RawPtr(ty::TypeAndMut { ty: b, .. })) => {
|
||||||
assert!(bx.cx().type_is_sized(a));
|
assert!(bx.cx().type_is_sized(a));
|
||||||
let ptr_ty = bx.cx().type_ptr_to(bx.cx().layout_of(b).llvm_type(bx.cx()));
|
let ptr_ty = bx.cx().type_ptr_to(bx.cx().backend_type(&bx.cx().layout_of(b)));
|
||||||
(bx.pointercast(src, ptr_ty), unsized_info(bx.cx(), a, b, None))
|
(bx.pointercast(src, ptr_ty), unsized_info(bx.cx(), a, b, None))
|
||||||
}
|
}
|
||||||
(&ty::Adt(def_a, _), &ty::Adt(def_b, _)) if def_a.is_box() && def_b.is_box() => {
|
(&ty::Adt(def_a, _), &ty::Adt(def_b, _)) if def_a.is_box() && def_b.is_box() => {
|
||||||
let (a, b) = (src_ty.boxed_ty(), dst_ty.boxed_ty());
|
let (a, b) = (src_ty.boxed_ty(), dst_ty.boxed_ty());
|
||||||
assert!(bx.cx().type_is_sized(a));
|
assert!(bx.cx().type_is_sized(a));
|
||||||
let ptr_ty = bx.cx().type_ptr_to(bx.cx().layout_of(b).llvm_type(bx.cx()));
|
let ptr_ty = bx.cx().type_ptr_to(bx.cx().backend_type(&bx.cx().layout_of(b)));
|
||||||
(bx.pointercast(src, ptr_ty), unsized_info(bx.cx(), a, b, None))
|
(bx.pointercast(src, ptr_ty), unsized_info(bx.cx(), a, b, None))
|
||||||
}
|
}
|
||||||
(&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => {
|
(&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => {
|
||||||
|
@ -263,8 +263,8 @@ pub fn unsize_thin_ptr(
|
||||||
}
|
}
|
||||||
let (lldata, llextra) = result.unwrap();
|
let (lldata, llextra) = result.unwrap();
|
||||||
// HACK(eddyb) have to bitcast pointers until LLVM removes pointee types.
|
// HACK(eddyb) have to bitcast pointers until LLVM removes pointee types.
|
||||||
(bx.bitcast(lldata, dst_layout.scalar_pair_element_llvm_type(bx.cx(), 0, true)),
|
(bx.bitcast(lldata, bx.cx().scalar_pair_element_backend_type(&dst_layout, 0, true)),
|
||||||
bx.bitcast(llextra, dst_layout.scalar_pair_element_llvm_type(bx.cx(), 1, true)))
|
bx.bitcast(llextra, bx.cx().scalar_pair_element_backend_type(&dst_layout, 1, true)))
|
||||||
}
|
}
|
||||||
_ => bug!("unsize_thin_ptr: called on bad types"),
|
_ => bug!("unsize_thin_ptr: called on bad types"),
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use attributes;
|
use attributes;
|
||||||
use common;
|
|
||||||
use llvm;
|
use llvm;
|
||||||
use rustc::dep_graph::DepGraphSafe;
|
use rustc::dep_graph::DepGraphSafe;
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
|
@ -746,31 +745,6 @@ impl<'b, 'tcx> CodegenCx<'b, 'tcx> {
|
||||||
llfn
|
llfn
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool {
|
|
||||||
common::type_needs_drop(self.tcx, ty)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn type_is_sized(&self, ty: Ty<'tcx>) -> bool {
|
|
||||||
common::type_is_sized(self.tcx, ty)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
|
|
||||||
common::type_is_freeze(self.tcx, ty)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool {
|
|
||||||
use syntax_pos::DUMMY_SP;
|
|
||||||
if ty.is_sized(self.tcx.at(DUMMY_SP), ty::ParamEnv::reveal_all()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let tail = self.tcx.struct_tail(ty);
|
|
||||||
match tail.sty {
|
|
||||||
ty::Foreign(..) => false,
|
|
||||||
ty::Str | ty::Slice(..) | ty::Dynamic(..) => true,
|
|
||||||
_ => bug!("unexpected unsized tail: {:?}", tail.sty),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ty::layout::HasDataLayout for CodegenCx<'ll, 'tcx> {
|
impl ty::layout::HasDataLayout for CodegenCx<'ll, 'tcx> {
|
||||||
|
|
|
@ -20,7 +20,7 @@ use meth;
|
||||||
use rustc::ty::layout::{LayoutOf, HasTyCtxt};
|
use rustc::ty::layout::{LayoutOf, HasTyCtxt};
|
||||||
use rustc::ty::{self, Ty};
|
use rustc::ty::{self, Ty};
|
||||||
use value::Value;
|
use value::Value;
|
||||||
use interfaces::{BuilderMethods, ConstMethods};
|
use interfaces::*;
|
||||||
|
|
||||||
pub fn size_and_align_of_dst(
|
pub fn size_and_align_of_dst(
|
||||||
bx: &Builder<'_, 'll, 'tcx>,
|
bx: &Builder<'_, 'll, 'tcx>,
|
||||||
|
|
|
@ -61,10 +61,21 @@ pub trait DerivedTypeMethods<'tcx>: Backend<'tcx> {
|
||||||
fn type_from_integer(&self, i: layout::Integer) -> Self::Type;
|
fn type_from_integer(&self, i: layout::Integer) -> Self::Type;
|
||||||
fn type_pointee_for_abi_align(&self, align: Align) -> Self::Type;
|
fn type_pointee_for_abi_align(&self, align: Align) -> Self::Type;
|
||||||
fn type_padding_filler(&self, size: Size, align: Align) -> Self::Type;
|
fn type_padding_filler(&self, size: Size, align: Align) -> Self::Type;
|
||||||
|
|
||||||
|
fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool;
|
||||||
|
fn type_is_sized(&self, ty: Ty<'tcx>) -> bool;
|
||||||
|
fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool;
|
||||||
|
fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait LayoutTypeMethods<'tcx>: Backend<'tcx> {
|
pub trait LayoutTypeMethods<'tcx>: Backend<'tcx> {
|
||||||
fn backend_type(&self, ty: TyLayout<'tcx>) -> Self::Type;
|
fn backend_type(&self, ty: &TyLayout<'tcx>) -> Self::Type;
|
||||||
|
fn scalar_pair_element_backend_type<'a>(
|
||||||
|
&self,
|
||||||
|
ty: &TyLayout<'tcx>,
|
||||||
|
index: usize,
|
||||||
|
immediate: bool
|
||||||
|
) -> Self::Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait TypeMethods<'tcx>:
|
pub trait TypeMethods<'tcx>:
|
||||||
|
|
|
@ -22,6 +22,7 @@ use rustc::ty::layout::LayoutOf;
|
||||||
use type_of::LayoutLlvmExt;
|
use type_of::LayoutLlvmExt;
|
||||||
use super::FunctionCx;
|
use super::FunctionCx;
|
||||||
use value::Value;
|
use value::Value;
|
||||||
|
use interfaces::*;
|
||||||
|
|
||||||
pub fn non_ssa_locals(fx: &FunctionCx<'a, 'll, 'tcx, &'ll Value>) -> BitSet<mir::Local> {
|
pub fn non_ssa_locals(fx: &FunctionCx<'a, 'll, 'tcx, &'ll Value>) -> BitSet<mir::Local> {
|
||||||
let mir = fx.mir;
|
let mir = fx.mir;
|
||||||
|
|
|
@ -25,7 +25,7 @@ use type_::Type;
|
||||||
use type_of::LayoutLlvmExt;
|
use type_of::LayoutLlvmExt;
|
||||||
use value::Value;
|
use value::Value;
|
||||||
|
|
||||||
use interfaces::{BuilderMethods, ConstMethods, BaseTypeMethods, IntrinsicDeclarationMethods};
|
use interfaces::*;
|
||||||
|
|
||||||
use super::{FunctionCx, LocalRef};
|
use super::{FunctionCx, LocalRef};
|
||||||
use super::operand::{OperandRef, OperandValue};
|
use super::operand::{OperandRef, OperandValue};
|
||||||
|
|
|
@ -20,9 +20,9 @@ use value::Value;
|
||||||
|
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use rustc::ty::layout::{self, Align, Size};
|
use rustc::ty::layout::{self, Align, Size, HasTyCtxt};
|
||||||
use rustc::util::nodemap::FxHashMap;
|
use rustc::util::nodemap::FxHashMap;
|
||||||
use rustc::ty::Ty;
|
use rustc::ty::{self, Ty};
|
||||||
use rustc::ty::layout::TyLayout;
|
use rustc::ty::layout::TyLayout;
|
||||||
use rustc_data_structures::small_c_str::SmallCStr;
|
use rustc_data_structures::small_c_str::SmallCStr;
|
||||||
use common::{self, TypeKind};
|
use common::{self, TypeKind};
|
||||||
|
@ -365,10 +365,44 @@ impl DerivedTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||||
assert_eq!(size % unit_size, 0);
|
assert_eq!(size % unit_size, 0);
|
||||||
self.type_array(self.type_from_integer(unit), size / unit_size)
|
self.type_array(self.type_from_integer(unit), size / unit_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool {
|
||||||
|
common::type_needs_drop(self.tcx(), ty)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn type_is_sized(&self, ty: Ty<'tcx>) -> bool {
|
||||||
|
common::type_is_sized(self.tcx(), ty)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
|
||||||
|
common::type_is_freeze(self.tcx(), ty)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool {
|
||||||
|
use syntax_pos::DUMMY_SP;
|
||||||
|
if ty.is_sized(self.tcx().at(DUMMY_SP), ty::ParamEnv::reveal_all()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let tail = self.tcx().struct_tail(ty);
|
||||||
|
match tail.sty {
|
||||||
|
ty::Foreign(..) => false,
|
||||||
|
ty::Str | ty::Slice(..) | ty::Dynamic(..) => true,
|
||||||
|
_ => bug!("unexpected unsized tail: {:?}", tail.sty),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LayoutTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
impl LayoutTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||||
fn backend_type(&self, ty: TyLayout<'tcx>) -> &'ll Type {
|
fn backend_type(&self, ty: &TyLayout<'tcx>) -> &'ll Type {
|
||||||
ty.llvm_type(&self)
|
ty.llvm_type(&self)
|
||||||
}
|
}
|
||||||
|
fn scalar_pair_element_backend_type<'a>(
|
||||||
|
&self,
|
||||||
|
ty: &TyLayout<'tcx>,
|
||||||
|
index: usize,
|
||||||
|
immediate: bool
|
||||||
|
) -> &'ll Type {
|
||||||
|
ty.scalar_pair_element_llvm_type(&self, index, immediate)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue