rustc: Unify fat pointer ABI constants.
This merges the `trt_field_*`, `fn_field_*` and `slice_elt_*` constants into two `FAT_PTR_*` constants. This resolves the first part of #18590.
This commit is contained in:
parent
47c1d437c9
commit
b781c8b08e
@ -14,17 +14,14 @@ pub const box_field_refcnt: uint = 0u;
|
||||
pub const box_field_drop_glue: uint = 1u;
|
||||
pub const box_field_body: uint = 4u;
|
||||
|
||||
// FIXME(18590) although we have three different layouts here, the compiler relies on
|
||||
// them being the same. We should replace them with one set of constants.
|
||||
/// The first half of a fat pointer.
|
||||
/// - For a closure, this is the code address.
|
||||
/// - For an object or trait instance, this is the address of the box.
|
||||
/// - For a slice, this is the base address.
|
||||
pub const FAT_PTR_ADDR: uint = 0;
|
||||
|
||||
// The two halves of a closure: code and environment.
|
||||
pub const fn_field_code: uint = 0u;
|
||||
pub const fn_field_box: uint = 1u;
|
||||
|
||||
// The two fields of a trait object/trait instance: vtable and box.
|
||||
// The vtable contains the type descriptor as first element.
|
||||
pub const trt_field_box: uint = 0u;
|
||||
pub const trt_field_vtable: uint = 1u;
|
||||
|
||||
pub const slice_elt_base: uint = 0u;
|
||||
pub const slice_elt_len: uint = 1u;
|
||||
/// The second half of a fat pointer.
|
||||
/// - For a closure, this is the address of the environment.
|
||||
/// - For an object or trait instance, this is the address of the vtable.
|
||||
/// - For a slice, this is the length.
|
||||
pub const FAT_PTR_EXTRA: uint = 1u;
|
||||
|
@ -649,8 +649,8 @@ fn bind_subslice_pat(bcx: Block,
|
||||
ty::mt {ty: vt.unit_ty, mutbl: ast::MutImmutable});
|
||||
let scratch = rvalue_scratch_datum(bcx, slice_ty, "");
|
||||
Store(bcx, slice_begin,
|
||||
GEPi(bcx, scratch.val, &[0u, abi::slice_elt_base]));
|
||||
Store(bcx, slice_len, GEPi(bcx, scratch.val, &[0u, abi::slice_elt_len]));
|
||||
GEPi(bcx, scratch.val, &[0u, abi::FAT_PTR_ADDR]));
|
||||
Store(bcx, slice_len, GEPi(bcx, scratch.val, &[0u, abi::FAT_PTR_EXTRA]));
|
||||
scratch.val
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ use std::num::Int;
|
||||
use std::rc::Rc;
|
||||
|
||||
use llvm::{ValueRef, True, IntEQ, IntNE};
|
||||
use back::abi::slice_elt_base;
|
||||
use back::abi;
|
||||
use middle::subst;
|
||||
use middle::subst::Subst;
|
||||
use trans::_match;
|
||||
@ -684,7 +684,7 @@ fn struct_wrapped_nullable_bitdiscr(bcx: Block, nndiscr: Disr, ptrfield: Pointer
|
||||
scrutinee: ValueRef) -> ValueRef {
|
||||
let llptrptr = match ptrfield {
|
||||
ThinPointer(field) => GEPi(bcx, scrutinee, &[0, field]),
|
||||
FatPointer(field) => GEPi(bcx, scrutinee, &[0, field, slice_elt_base])
|
||||
FatPointer(field) => GEPi(bcx, scrutinee, &[0, field, abi::FAT_PTR_ADDR])
|
||||
};
|
||||
let llptr = Load(bcx, llptrptr);
|
||||
let cmp = if nndiscr == 0 { IntEQ } else { IntNE };
|
||||
@ -782,7 +782,7 @@ pub fn trans_set_discr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>,
|
||||
(GEPi(bcx, val, &[0, field]),
|
||||
type_of::type_of(bcx.ccx(), nonnull.fields[field])),
|
||||
FatPointer(field) => {
|
||||
let v = GEPi(bcx, val, &[0, field, slice_elt_base]);
|
||||
let v = GEPi(bcx, val, &[0, field, abi::FAT_PTR_ADDR]);
|
||||
(v, val_ty(v).element_type())
|
||||
}
|
||||
};
|
||||
@ -1118,7 +1118,7 @@ pub fn const_get_discrim(ccx: &CrateContext, r: &Repr, val: ValueRef)
|
||||
StructWrappedNullablePointer { nndiscr, ptrfield, .. } => {
|
||||
let (idx, sub_idx) = match ptrfield {
|
||||
ThinPointer(field) => (field, None),
|
||||
FatPointer(field) => (field, Some(slice_elt_base))
|
||||
FatPointer(field) => (field, Some(abi::FAT_PTR_ADDR))
|
||||
};
|
||||
if is_null(const_struct_field(ccx, val, idx, sub_idx)) {
|
||||
/* subtraction as uint is ok because nndiscr is either 0 or 1 */
|
||||
|
@ -705,8 +705,8 @@ pub fn iter_structural_ty<'a, 'blk, 'tcx>(cx: Block<'blk, 'tcx>,
|
||||
let (data_ptr, info) = if ty::type_is_sized(cx.tcx(), t) {
|
||||
(av, None)
|
||||
} else {
|
||||
let data = GEPi(cx, av, &[0, abi::slice_elt_base]);
|
||||
let info = GEPi(cx, av, &[0, abi::slice_elt_len]);
|
||||
let data = GEPi(cx, av, &[0, abi::FAT_PTR_ADDR]);
|
||||
let info = GEPi(cx, av, &[0, abi::FAT_PTR_EXTRA]);
|
||||
(Load(cx, data), Some(Load(cx, info)))
|
||||
};
|
||||
|
||||
@ -724,8 +724,8 @@ pub fn iter_structural_ty<'a, 'blk, 'tcx>(cx: Block<'blk, 'tcx>,
|
||||
} else {
|
||||
let boxed_ty = ty::mk_open(cx.tcx(), field_ty);
|
||||
let scratch = datum::rvalue_scratch_datum(cx, boxed_ty, "__fat_ptr_iter");
|
||||
Store(cx, llfld_a, GEPi(cx, scratch.val, &[0, abi::slice_elt_base]));
|
||||
Store(cx, info.unwrap(), GEPi(cx, scratch.val, &[0, abi::slice_elt_len]));
|
||||
Store(cx, llfld_a, GEPi(cx, scratch.val, &[0, abi::FAT_PTR_ADDR]));
|
||||
Store(cx, info.unwrap(), GEPi(cx, scratch.val, &[0, abi::FAT_PTR_EXTRA]));
|
||||
scratch.val
|
||||
};
|
||||
cx = f(cx, val, field_ty);
|
||||
|
@ -724,9 +724,9 @@ pub fn trans_call_inner<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
// Closures are represented as (llfn, llclosure) pair:
|
||||
// load the requisite values out.
|
||||
let pair = d.to_llref();
|
||||
let llfn = GEPi(bcx, pair, &[0u, abi::fn_field_code]);
|
||||
let llfn = GEPi(bcx, pair, &[0u, abi::FAT_PTR_ADDR]);
|
||||
let llfn = Load(bcx, llfn);
|
||||
let llenv = GEPi(bcx, pair, &[0u, abi::fn_field_box]);
|
||||
let llenv = GEPi(bcx, pair, &[0u, abi::FAT_PTR_EXTRA]);
|
||||
let llenv = Load(bcx, llenv);
|
||||
(llfn, Some(llenv), None)
|
||||
}
|
||||
|
@ -339,9 +339,9 @@ fn load_unboxed_closure_environment<'blk, 'tcx>(
|
||||
}
|
||||
|
||||
fn fill_fn_pair(bcx: Block, pair: ValueRef, llfn: ValueRef, llenvptr: ValueRef) {
|
||||
Store(bcx, llfn, GEPi(bcx, pair, &[0u, abi::fn_field_code]));
|
||||
Store(bcx, llfn, GEPi(bcx, pair, &[0u, abi::FAT_PTR_ADDR]));
|
||||
let llenvptr = PointerCast(bcx, llenvptr, Type::i8p(bcx.ccx()));
|
||||
Store(bcx, llenvptr, GEPi(bcx, pair, &[0u, abi::fn_field_box]));
|
||||
Store(bcx, llenvptr, GEPi(bcx, pair, &[0u, abi::FAT_PTR_EXTRA]));
|
||||
}
|
||||
|
||||
#[deriving(PartialEq)]
|
||||
|
@ -264,8 +264,8 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, e: &ast::Expr)
|
||||
ty::ty_vec(unit_ty, Some(len)) => {
|
||||
let llunitty = type_of::type_of(cx, unit_ty);
|
||||
let llptr = const_ptrcast(cx, llconst, llunitty);
|
||||
assert_eq!(abi::slice_elt_base, 0);
|
||||
assert_eq!(abi::slice_elt_len, 1);
|
||||
assert_eq!(abi::FAT_PTR_ADDR, 0);
|
||||
assert_eq!(abi::FAT_PTR_EXTRA, 1);
|
||||
llconst = C_struct(cx, &[
|
||||
llptr,
|
||||
C_uint(cx, len)
|
||||
|
@ -171,11 +171,11 @@ pub fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
}
|
||||
|
||||
pub fn get_len(bcx: Block, fat_ptr: ValueRef) -> ValueRef {
|
||||
GEPi(bcx, fat_ptr, &[0u, abi::slice_elt_len])
|
||||
GEPi(bcx, fat_ptr, &[0u, abi::FAT_PTR_EXTRA])
|
||||
}
|
||||
|
||||
pub fn get_dataptr(bcx: Block, fat_ptr: ValueRef) -> ValueRef {
|
||||
GEPi(bcx, fat_ptr, &[0u, abi::slice_elt_base])
|
||||
GEPi(bcx, fat_ptr, &[0u, abi::FAT_PTR_ADDR])
|
||||
}
|
||||
|
||||
fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
|
@ -196,7 +196,7 @@ fn trans_struct_drop_flag<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
let struct_data = if ty::type_is_sized(bcx.tcx(), t) {
|
||||
v0
|
||||
} else {
|
||||
let llval = GEPi(bcx, v0, &[0, abi::slice_elt_base]);
|
||||
let llval = GEPi(bcx, v0, &[0, abi::FAT_PTR_ADDR]);
|
||||
Load(bcx, llval)
|
||||
};
|
||||
let drop_flag = unpack_datum!(bcx, adt::trans_drop_flag_ptr(bcx, &*repr, struct_data));
|
||||
@ -237,8 +237,8 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
let (struct_data, info) = if ty::type_is_sized(bcx.tcx(), t) {
|
||||
(v0, None)
|
||||
} else {
|
||||
let data = GEPi(bcx, v0, &[0, abi::slice_elt_base]);
|
||||
let info = GEPi(bcx, v0, &[0, abi::slice_elt_len]);
|
||||
let data = GEPi(bcx, v0, &[0, abi::FAT_PTR_ADDR]);
|
||||
let info = GEPi(bcx, v0, &[0, abi::FAT_PTR_EXTRA]);
|
||||
(Load(bcx, data), Some(Load(bcx, info)))
|
||||
};
|
||||
|
||||
@ -255,14 +255,14 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
// The dtor expects a fat pointer, so make one, even if we have to fake it.
|
||||
let boxed_ty = ty::mk_open(bcx.tcx(), t);
|
||||
let scratch = datum::rvalue_scratch_datum(bcx, boxed_ty, "__fat_ptr_drop_self");
|
||||
Store(bcx, value, GEPi(bcx, scratch.val, &[0, abi::slice_elt_base]));
|
||||
Store(bcx, value, GEPi(bcx, scratch.val, &[0, abi::FAT_PTR_ADDR]));
|
||||
Store(bcx,
|
||||
// If we just had a thin pointer, make a fat pointer by sticking
|
||||
// null where we put the unsizing info. This works because t
|
||||
// is a sized type, so we will only unpack the fat pointer, never
|
||||
// use the fake info.
|
||||
info.unwrap_or(C_null(Type::i8p(bcx.ccx()))),
|
||||
GEPi(bcx, scratch.val, &[0, abi::slice_elt_len]));
|
||||
GEPi(bcx, scratch.val, &[0, abi::FAT_PTR_EXTRA]));
|
||||
PointerCast(variant_cx, scratch.val, params[0])
|
||||
} else {
|
||||
PointerCast(variant_cx, value, params[0])
|
||||
@ -280,8 +280,8 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
} else {
|
||||
let boxed_ty = ty::mk_open(bcx.tcx(), *ty);
|
||||
let scratch = datum::rvalue_scratch_datum(bcx, boxed_ty, "__fat_ptr_drop_field");
|
||||
Store(bcx, llfld_a, GEPi(bcx, scratch.val, &[0, abi::slice_elt_base]));
|
||||
Store(bcx, info.unwrap(), GEPi(bcx, scratch.val, &[0, abi::slice_elt_len]));
|
||||
Store(bcx, llfld_a, GEPi(bcx, scratch.val, &[0, abi::FAT_PTR_ADDR]));
|
||||
Store(bcx, info.unwrap(), GEPi(bcx, scratch.val, &[0, abi::FAT_PTR_EXTRA]));
|
||||
scratch.val
|
||||
};
|
||||
variant_cx.fcx.schedule_drop_mem(cleanup::CustomScope(field_scope),
|
||||
@ -369,11 +369,11 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>)
|
||||
tvec::make_drop_glue_unboxed(bcx, v0, unit_ty, true)
|
||||
}
|
||||
ty::ty_trait(..) => {
|
||||
let lluniquevalue = GEPi(bcx, v0, &[0, abi::trt_field_box]);
|
||||
let lluniquevalue = GEPi(bcx, v0, &[0, abi::FAT_PTR_ADDR]);
|
||||
// Only drop the value when it is non-null
|
||||
let concrete_ptr = Load(bcx, lluniquevalue);
|
||||
with_cond(bcx, IsNotNull(bcx, concrete_ptr), |bcx| {
|
||||
let dtor_ptr = Load(bcx, GEPi(bcx, v0, &[0, abi::trt_field_vtable]));
|
||||
let dtor_ptr = Load(bcx, GEPi(bcx, v0, &[0, abi::FAT_PTR_EXTRA]));
|
||||
let dtor = Load(bcx, dtor_ptr);
|
||||
Call(bcx,
|
||||
dtor,
|
||||
@ -383,12 +383,12 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>)
|
||||
})
|
||||
}
|
||||
ty::ty_struct(..) if !ty::type_is_sized(bcx.tcx(), content_ty) => {
|
||||
let llval = GEPi(bcx, v0, &[0, abi::slice_elt_base]);
|
||||
let llval = GEPi(bcx, v0, &[0, abi::FAT_PTR_ADDR]);
|
||||
let llbox = Load(bcx, llval);
|
||||
let not_null = IsNotNull(bcx, llbox);
|
||||
with_cond(bcx, not_null, |bcx| {
|
||||
let bcx = drop_ty(bcx, v0, content_ty, None);
|
||||
let info = GEPi(bcx, v0, &[0, abi::slice_elt_len]);
|
||||
let info = GEPi(bcx, v0, &[0, abi::FAT_PTR_EXTRA]);
|
||||
let info = Load(bcx, info);
|
||||
let (llsize, llalign) = size_and_align_of_dst(bcx, content_ty, info);
|
||||
trans_exchange_free_dyn(bcx, llbox, llsize, llalign)
|
||||
@ -440,7 +440,7 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>)
|
||||
t,
|
||||
|bb, vv, tt| drop_ty(bb, vv, tt, None)),
|
||||
ty::ty_closure(ref f) if f.store == ty::UniqTraitStore => {
|
||||
let box_cell_v = GEPi(bcx, v0, &[0u, abi::fn_field_box]);
|
||||
let box_cell_v = GEPi(bcx, v0, &[0u, abi::FAT_PTR_EXTRA]);
|
||||
let env = Load(bcx, box_cell_v);
|
||||
let env_ptr_ty = Type::at_box(bcx.ccx(), Type::i8(bcx.ccx())).ptr_to();
|
||||
let env = PointerCast(bcx, env, env_ptr_ty);
|
||||
@ -456,8 +456,8 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>)
|
||||
// above), because this happens for a trait field in an unsized
|
||||
// struct. If anything is null, it is the whole struct and we won't
|
||||
// get here.
|
||||
let lluniquevalue = GEPi(bcx, v0, &[0, abi::trt_field_box]);
|
||||
let dtor_ptr = Load(bcx, GEPi(bcx, v0, &[0, abi::trt_field_vtable]));
|
||||
let lluniquevalue = GEPi(bcx, v0, &[0, abi::FAT_PTR_ADDR]);
|
||||
let dtor_ptr = Load(bcx, GEPi(bcx, v0, &[0, abi::FAT_PTR_EXTRA]));
|
||||
let dtor = Load(bcx, dtor_ptr);
|
||||
Call(bcx,
|
||||
dtor,
|
||||
|
@ -481,7 +481,7 @@ pub fn trans_trait_callee_from_llval<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
|
||||
// Load the data pointer from the object.
|
||||
debug!("(translating trait callee) loading second index from pair");
|
||||
let llboxptr = GEPi(bcx, llpair, &[0u, abi::trt_field_box]);
|
||||
let llboxptr = GEPi(bcx, llpair, &[0u, abi::FAT_PTR_ADDR]);
|
||||
let llbox = Load(bcx, llboxptr);
|
||||
let llself = PointerCast(bcx, llbox, Type::i8p(ccx));
|
||||
|
||||
@ -503,7 +503,7 @@ pub fn trans_trait_callee_from_llval<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
let llvtable = Load(bcx,
|
||||
PointerCast(bcx,
|
||||
GEPi(bcx, llpair,
|
||||
&[0u, abi::trt_field_vtable]),
|
||||
&[0u, abi::FAT_PTR_EXTRA]),
|
||||
Type::vtable(ccx).ptr_to().ptr_to()));
|
||||
let mptr = Load(bcx, GEPi(bcx, llvtable, &[0u, n_method + VTABLE_OFFSET]));
|
||||
let mptr = PointerCast(bcx, mptr, llcallee_ty.ptr_to());
|
||||
@ -761,13 +761,13 @@ pub fn trans_trait_cast<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
let llbox_ty = type_of(bcx.ccx(), datum_ty);
|
||||
|
||||
// Store the pointer into the first half of pair.
|
||||
let llboxdest = GEPi(bcx, lldest, &[0u, abi::trt_field_box]);
|
||||
let llboxdest = GEPi(bcx, lldest, &[0u, abi::FAT_PTR_ADDR]);
|
||||
let llboxdest = PointerCast(bcx, llboxdest, llbox_ty.ptr_to());
|
||||
bcx = datum.store_to(bcx, llboxdest);
|
||||
|
||||
// Store the vtable into the second half of pair.
|
||||
let vtable = get_vtable(bcx, datum_ty, trait_ref);
|
||||
let llvtabledest = GEPi(bcx, lldest, &[0u, abi::trt_field_vtable]);
|
||||
let llvtabledest = GEPi(bcx, lldest, &[0u, abi::FAT_PTR_EXTRA]);
|
||||
let llvtabledest = PointerCast(bcx, llvtabledest, val_ty(vtable).ptr_to());
|
||||
Store(bcx, vtable, llvtabledest);
|
||||
|
||||
|
@ -231,8 +231,8 @@ pub fn trans_lit_str<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
let llbytes = C_uint(bcx.ccx(), bytes);
|
||||
let llcstr = C_cstr(bcx.ccx(), str_lit, false);
|
||||
let llcstr = llvm::LLVMConstPointerCast(llcstr, Type::i8p(bcx.ccx()).to_ref());
|
||||
Store(bcx, llcstr, GEPi(bcx, lldest, &[0u, abi::slice_elt_base]));
|
||||
Store(bcx, llbytes, GEPi(bcx, lldest, &[0u, abi::slice_elt_len]));
|
||||
Store(bcx, llcstr, GEPi(bcx, lldest, &[0u, abi::FAT_PTR_ADDR]));
|
||||
Store(bcx, llbytes, GEPi(bcx, lldest, &[0u, abi::FAT_PTR_EXTRA]));
|
||||
bcx
|
||||
}
|
||||
}
|
||||
@ -401,8 +401,8 @@ pub fn get_fixed_base_and_len(bcx: Block,
|
||||
fn get_slice_base_and_len(bcx: Block,
|
||||
llval: ValueRef)
|
||||
-> (ValueRef, ValueRef) {
|
||||
let base = Load(bcx, GEPi(bcx, llval, &[0u, abi::slice_elt_base]));
|
||||
let len = Load(bcx, GEPi(bcx, llval, &[0u, abi::slice_elt_len]));
|
||||
let base = Load(bcx, GEPi(bcx, llval, &[0u, abi::FAT_PTR_ADDR]));
|
||||
let len = Load(bcx, GEPi(bcx, llval, &[0u, abi::FAT_PTR_EXTRA]));
|
||||
(base, len)
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user