Skip to content

rustc: Unify fat pointer ABI constants. #18856

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

Merged
merged 2 commits into from
Nov 23, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 12 additions & 18 deletions src/librustc_back/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,17 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(non_upper_case_globals)]
pub const BOX_FIELD_DROP_GLUE: uint = 1u;
pub const BOX_FIELD_BODY: uint = 4u;

pub const box_field_refcnt: uint = 0u;
pub const box_field_drop_glue: uint = 1u;
pub const box_field_body: uint = 4u;
/// 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;

// 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 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;
4 changes: 2 additions & 2 deletions src/librustc_trans/trans/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
8 changes: 4 additions & 4 deletions src/librustc_trans/trans/adt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 };
Expand Down Expand Up @@ -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())
}
};
Expand Down Expand Up @@ -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 */
Expand Down
12 changes: 6 additions & 6 deletions src/librustc_trans/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ pub fn at_box_body<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let ccx = bcx.ccx();
let ty = Type::at_box(ccx, type_of(ccx, body_t));
let boxptr = PointerCast(bcx, boxptr, ty.ptr_to());
GEPi(bcx, boxptr, &[0u, abi::box_field_body])
GEPi(bcx, boxptr, &[0u, abi::BOX_FIELD_BODY])
}

fn require_alloc_fn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
Expand Down Expand Up @@ -394,7 +394,7 @@ pub fn malloc_raw_dyn_proc<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: Ty<'tcx>)

// Allocate space and store the destructor pointer:
let Result {bcx, val: llbox} = malloc_raw_dyn(bcx, ptr_llty, t, size, llalign);
let dtor_ptr = GEPi(bcx, llbox, &[0u, abi::box_field_drop_glue]);
let dtor_ptr = GEPi(bcx, llbox, &[0u, abi::BOX_FIELD_DROP_GLUE]);
let drop_glue_field_ty = type_of(ccx, ty::mk_nil_ptr(bcx.tcx()));
let drop_glue = PointerCast(bcx, glue::get_drop_glue(ccx, ty::mk_uniq(bcx.tcx(), t)),
drop_glue_field_ty);
Expand Down Expand Up @@ -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)))
};

Expand All @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_trans/trans/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
6 changes: 3 additions & 3 deletions src/librustc_trans/trans/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ pub fn store_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
bv.to_string(ccx)).as_slice());
}

let bound_data = GEPi(bcx, llbox, &[0u, abi::box_field_body, i]);
let bound_data = GEPi(bcx, llbox, &[0u, abi::BOX_FIELD_BODY, i]);

match bv.action {
ast::CaptureByValue => {
Expand Down Expand Up @@ -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)]
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_trans/trans/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_trans/trans/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>,
Expand Down
30 changes: 15 additions & 15 deletions src/librustc_trans/trans/glue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -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)))
};

Expand All @@ -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])
Expand All @@ -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),
Expand Down Expand Up @@ -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,
Expand All @@ -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)
Expand Down Expand Up @@ -440,12 +440,12 @@ 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);
with_cond(bcx, IsNotNull(bcx, env), |bcx| {
let dtor_ptr = GEPi(bcx, env, &[0u, abi::box_field_drop_glue]);
let dtor_ptr = GEPi(bcx, env, &[0u, abi::BOX_FIELD_DROP_GLUE]);
let dtor = Load(bcx, dtor_ptr);
Call(bcx, dtor, &[PointerCast(bcx, box_cell_v, Type::i8p(bcx.ccx()))], None);
bcx
Expand All @@ -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,
Expand Down
8 changes: 4 additions & 4 deletions src/librustc_trans/trans/meth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand All @@ -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());
Expand Down Expand Up @@ -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);

Expand Down
8 changes: 4 additions & 4 deletions src/librustc_trans/trans/tvec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
Expand Down Expand Up @@ -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)
}

Expand Down