Skip to content

Commit

Permalink
Support binding of methods off boxed iface values
Browse files Browse the repository at this point in the history
  • Loading branch information
marijnh committed Mar 16, 2012
1 parent 5f20c94 commit 15a325f
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 12 deletions.
6 changes: 3 additions & 3 deletions src/rustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1745,7 +1745,7 @@ type lval_result = {bcx: block, val: ValueRef, kind: lval_kind};
enum callee_env {
null_env,
is_closure,
self_env(ValueRef, ty::t),
self_env(ValueRef, ty::t, option<ValueRef>),
}
type lval_maybe_callee = {bcx: block,
val: ValueRef,
Expand Down Expand Up @@ -2341,7 +2341,7 @@ fn trans_lval(cx: block, e: @ast::expr) -> lval_result {
}

fn lval_maybe_callee_to_lval(c: lval_maybe_callee, ty: ty::t) -> lval_result {
let must_bind = alt c.env { self_env(_, _) { true } _ { false } };
let must_bind = alt c.env { self_env(_, _, _) { true } _ { false } };
if must_bind {
let n_args = ty::ty_fn_args(ty).len();
let args = vec::from_elem(n_args, none);
Expand Down Expand Up @@ -2618,7 +2618,7 @@ fn trans_call_inner(in_cx: block, fn_expr_ty: ty::t,
null_env {
llvm::LLVMGetUndef(T_opaque_box_ptr(ccx))
}
self_env(e, _) {
self_env(e, _, _) {
PointerCast(bcx, e, T_opaque_box_ptr(ccx))
}
is_closure {
Expand Down
21 changes: 17 additions & 4 deletions src/rustc/middle/trans/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,8 +462,13 @@ fn trans_bind_1(cx: block, outgoing_fty: ty::t,
let src_loc = PointerCast(bcx, f_res.val, llclosurety);
([env_copy(src_loc, pair_ty, owned)], target_closure)
}
self_env(slf, slf_t) {
([env_copy(slf, slf_t, owned)], target_self(f_res.val))
self_env(slf, slf_t, none) {
([env_copy(slf, slf_t, owned)], target_static_self(f_res.val))
}
self_env(_, slf_t, some(slf)) {
let cast = PointerCast(bcx, f_res.val, T_ptr(T_nil()));
([env_copy(cast, ty::mk_nil_ptr(ccx.tcx), owned_imm),
env_copy(slf, slf_t, owned_imm)], target_self)
}
};

Expand Down Expand Up @@ -617,7 +622,8 @@ fn make_opaque_cbox_free_glue(
enum target_info {
target_closure,
target_static(ValueRef),
target_self(ValueRef),
target_self,
target_static_self(ValueRef),
}

// pth is cx.path
Expand Down Expand Up @@ -698,7 +704,14 @@ fn trans_bind_thunk(ccx: @crate_ctxt,
(bcx, GEPi(bcx, pair, [0, abi::fn_field_code]));
(lltargetfn, lltargetenv, 1)
}
target_self(fptr) {
target_self {
let fptr = Load(bcx, GEPi(bcx, llcdata,
[0, abi::closure_body_bindings, 0]));
let slfbox = GEPi(bcx, llcdata, [0, abi::closure_body_bindings, 1]);
let selfptr = GEPi(bcx, Load(bcx, slfbox), [0, abi::box_field_body]);
(fptr, PointerCast(bcx, selfptr, T_opaque_cbox_ptr(ccx)), 2)
}
target_static_self(fptr) {
let slfptr = GEPi(bcx, llcdata, [0, abi::closure_body_bindings, 0]);
(fptr, PointerCast(bcx, slfptr, T_opaque_cbox_ptr(ccx)), 1)
}
Expand Down
8 changes: 4 additions & 4 deletions src/rustc/middle/trans/impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ fn trans_method_callee(bcx: block, callee_id: ast::node_id,
alt origin {
typeck::method_static(did) {
let {bcx, val} = trans_self_arg(bcx, self);
{env: self_env(val, node_id_type(bcx, self.id))
{env: self_env(val, node_id_type(bcx, self.id), none)
with lval_static_fn(bcx, did, callee_id)}
}
typeck::method_param(iid, off, p, b) {
Expand Down Expand Up @@ -115,7 +115,7 @@ fn trans_monomorphized_callee(bcx: block, callee_id: ast::node_id,
let ty_substs = impl_substs +
vec::tailn(node_substs, node_substs.len() - n_m_tps);
let {bcx, val} = trans_self_arg(bcx, base);
{env: self_env(val, node_id_type(bcx, base.id))
{env: self_env(val, node_id_type(bcx, base.id), none)
with lval_static_fn_inner(bcx, mth_id, callee_id, ty_substs,
some(sub_origins))}
}
Expand All @@ -138,8 +138,8 @@ fn trans_iface_callee(bcx: block, base: @ast::expr,
let box = Load(bcx, GEPi(bcx, val, [0, 1]));
// FIXME[impl] I doubt this is alignment-safe
let self = GEPi(bcx, box, [0, abi::box_field_body]);
trans_vtable_callee(bcx, self_env(self, expr_ty(bcx, base)), vtable,
callee_id, n_method)
let env = self_env(self, ty::mk_opaque_box(bcx.tcx()), some(box));
trans_vtable_callee(bcx, env, vtable, callee_id, n_method)
}

fn find_vtable_in_fn_ctxt(ps: param_substs, n_param: uint, n_bound: uint)
Expand Down
6 changes: 5 additions & 1 deletion src/rustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export ty_nil, mk_nil, type_is_nil;
export ty_iface, mk_iface;
export ty_res, mk_res;
export ty_param, mk_param;
export ty_ptr, mk_ptr, mk_mut_ptr, type_is_unsafe_ptr;
export ty_ptr, mk_ptr, mk_mut_ptr, mk_nil_ptr, type_is_unsafe_ptr;
export ty_rptr, mk_rptr;
export ty_rec, mk_rec;
export ty_enum, mk_enum, type_is_enum;
Expand Down Expand Up @@ -482,6 +482,10 @@ fn mk_rptr(cx: ctxt, r: region, tm: mt) -> t { mk_t(cx, ty_rptr(r, tm)) }
fn mk_mut_ptr(cx: ctxt, ty: t) -> t { mk_ptr(cx, {ty: ty,
mutbl: ast::m_mutbl}) }

fn mk_nil_ptr(cx: ctxt) -> t {
mk_ptr(cx, {ty: mk_nil(cx), mutbl: ast::m_imm})
}

fn mk_vec(cx: ctxt, tm: mt) -> t { mk_t(cx, ty_vec(tm)) }

fn mk_rec(cx: ctxt, fs: [field]) -> t { mk_t(cx, ty_rec(fs)) }
Expand Down

0 comments on commit 15a325f

Please sign in to comment.