diff --git a/src/librustc/back/abi.rs b/src/librustc/back/abi.rs index 842dd89a7cd..e722e1a33c6 100644 --- a/src/librustc/back/abi.rs +++ b/src/librustc/back/abi.rs @@ -57,6 +57,13 @@ pub static n_tydesc_fields: uint = 8u; pub static fn_field_code: uint = 0u; pub static fn_field_box: uint = 1u; +// The three fields of a trait object/trait instance: vtable, box, and type +// description. +pub static trt_field_vtable: uint = 0u; +pub static trt_field_box: uint = 1u; +// This field is only present in unique trait objects, so it comes last. +pub static trt_field_tydesc: uint = 2u; + pub static vec_elt_fill: uint = 0u; pub static vec_elt_alloc: uint = 1u; diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 1f90b009ec6..53d218d390b 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -537,12 +537,12 @@ pub fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) { closure::make_closure_glue(bcx, v0, t, drop_ty) } ty::ty_trait(_, _, ty::BoxTraitStore, _) => { - let llbox = Load(bcx, GEPi(bcx, v0, [0u, 1u])); + let llbox = Load(bcx, GEPi(bcx, v0, [0u, abi::trt_field_box])); decr_refcnt_maybe_free(bcx, llbox, ty::mk_opaque_box(ccx.tcx)) } ty::ty_trait(_, _, ty::UniqTraitStore, _) => { - let lluniquevalue = GEPi(bcx, v0, [0, 1]); - let lltydesc = Load(bcx, GEPi(bcx, v0, [0, 2])); + let lluniquevalue = GEPi(bcx, v0, [0, abi::trt_field_box]); + let lltydesc = Load(bcx, GEPi(bcx, v0, [0, abi::trt_field_tydesc])); call_tydesc_glue_full(bcx, lluniquevalue, lltydesc, abi::tydesc_field_free_glue, None); bcx @@ -601,13 +601,13 @@ pub fn make_take_glue(bcx: block, v: ValueRef, t: ty::t) { closure::make_closure_glue(bcx, v, t, take_ty) } ty::ty_trait(_, _, ty::BoxTraitStore, _) => { - let llbox = Load(bcx, GEPi(bcx, v, [0u, 1u])); + let llbox = Load(bcx, GEPi(bcx, v, [0u, abi::trt_field_box])); incr_refcnt_of_boxed(bcx, llbox); bcx } ty::ty_trait(_, _, ty::UniqTraitStore, _) => { - let llval = GEPi(bcx, v, [0, 1]); - let lltydesc = Load(bcx, GEPi(bcx, v, [0, 2])); + let llval = GEPi(bcx, v, [0, abi::trt_field_box]); + let lltydesc = Load(bcx, GEPi(bcx, v, [0, abi::trt_field_tydesc])); call_tydesc_glue_full(bcx, llval, lltydesc, abi::tydesc_field_take_glue, None); bcx diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 90f9f93be2b..a90475d9ed0 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -637,14 +637,15 @@ pub fn trans_trait_callee_from_llval(bcx: block, val_str(bcx.ccx().tn, llpair)); let llvtable = Load(bcx, PointerCast(bcx, - GEPi(bcx, llpair, [0u, 0u]), + GEPi(bcx, llpair, + [0u, abi::trt_field_vtable]), T_ptr(T_ptr(T_vtable())))); // Load the box from the @Trait pair and GEP over the box header if // necessary: let mut llself; debug!("(translating trait callee) loading second index from pair"); - let llbox = Load(bcx, GEPi(bcx, llpair, [0u, 1u])); + let llbox = Load(bcx, GEPi(bcx, llpair, [0u, abi::trt_field_box])); // Munge `llself` appropriately for the type of `self` in the method. let self_mode; @@ -845,27 +846,30 @@ pub fn trans_trait_cast(bcx: block, match store { ty::RegionTraitStore(_) | ty::BoxTraitStore => { - let mut llboxdest = GEPi(bcx, lldest, [0u, 1u]); - // Just store the pointer into the pair. + let mut llboxdest = GEPi(bcx, lldest, [0u, abi::trt_field_box]); + // Just store the pointer into the pair. (Region/borrowed + // and boxed trait objects are represented as pairs, and + // have no type descriptor field.) llboxdest = PointerCast(bcx, llboxdest, T_ptr(type_of(bcx.ccx(), v_ty))); bcx = expr::trans_into(bcx, val, SaveIn(llboxdest)); } ty::UniqTraitStore => { - // Translate the uniquely-owned value into the second element of - // the triple. (The first element is the vtable.) - let mut llvaldest = GEPi(bcx, lldest, [0, 1]); + // Translate the uniquely-owned value in the + // triple. (Unique trait objects are represented as + // triples.) + let mut llvaldest = GEPi(bcx, lldest, [0, abi::trt_field_box]); llvaldest = PointerCast(bcx, llvaldest, T_ptr(type_of(bcx.ccx(), v_ty))); bcx = expr::trans_into(bcx, val, SaveIn(llvaldest)); - // Get the type descriptor of the wrapped value and store it into - // the third element of the triple as well. + // Get the type descriptor of the wrapped value and store + // it in the triple as well. let tydesc = get_tydesc(bcx.ccx(), v_ty); glue::lazily_emit_all_tydesc_glue(bcx.ccx(), tydesc); - let lltydescdest = GEPi(bcx, lldest, [0, 2]); + let lltydescdest = GEPi(bcx, lldest, [0, abi::trt_field_tydesc]); Store(bcx, tydesc.tydesc, lltydescdest); } } @@ -875,7 +879,7 @@ pub fn trans_trait_cast(bcx: block, let orig = resolve_vtable_in_fn_ctxt(bcx.fcx, orig); let vtable = get_vtable(bcx.ccx(), orig); Store(bcx, vtable, PointerCast(bcx, - GEPi(bcx, lldest, [0u, 0u]), + GEPi(bcx, lldest, [0u, abi::trt_field_vtable]), T_ptr(val_ty(vtable)))); bcx