Skip to content

Commit 0d60918

Browse files
committed
Most of the way through genericizing bind properly with new malloc path. Still getting the thunk call wrong.
1 parent 3473ff3 commit 0d60918

File tree

2 files changed

+56
-40
lines changed

2 files changed

+56
-40
lines changed

src/comp/middle/trans.rs

Lines changed: 49 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,10 @@ fn T_closure_ptr(type_names tn,
387387
TypeRef lltarget_ty,
388388
TypeRef llbindings_ty,
389389
uint n_ty_params) -> TypeRef {
390+
391+
// NB: keep this in sync with code in trans_bind; we're making
392+
// an LLVM typeref structure that has the same "shape" as the ty.t
393+
// it constructs.
390394
ret T_ptr(T_box(T_struct(vec(T_ptr(T_tydesc(tn)),
391395
lltarget_ty,
392396
llbindings_ty,
@@ -3322,7 +3326,7 @@ fn trans_bind_thunk(@crate_ctxt cx,
33223326
@ty.t incoming_fty,
33233327
@ty.t outgoing_fty,
33243328
vec[option.t[@ast.expr]] args,
3325-
TypeRef llclosure_ty,
3329+
@ty.t closure_ty,
33263330
vec[@ty.t] bound_tys,
33273331
uint ty_param_count) -> ValueRef {
33283332
// Construct a thunk-call with signature incoming_fty, and that copies
@@ -3335,21 +3339,15 @@ fn trans_bind_thunk(@crate_ctxt cx,
33353339
auto fcx = new_fn_ctxt(cx, llthunk);
33363340
auto bcx = new_top_block_ctxt(fcx);
33373341

3338-
auto llclosure = bcx.build.PointerCast(fcx.llenv, llclosure_ty);
3339-
3340-
auto llbody = bcx.build.GEP(llclosure,
3341-
vec(C_int(0),
3342-
C_int(abi.box_rc_field_body)));
3343-
3344-
auto lltarget = bcx.build.GEP(llbody,
3345-
vec(C_int(0),
3346-
C_int(abi.closure_elt_target)));
3347-
3348-
auto llbound = bcx.build.GEP(llbody,
3349-
vec(C_int(0),
3350-
C_int(abi.closure_elt_bindings)));
3342+
auto llclosure_ptr_ty = type_of(cx, plain_ty(ty.ty_box(closure_ty)));
3343+
auto llclosure = bcx.build.PointerCast(fcx.llenv, llclosure_ptr_ty);
33513344

3352-
auto lltargetclosure = bcx.build.GEP(lltarget,
3345+
auto lltarget = GEP_tup_like(bcx, closure_ty, llclosure,
3346+
vec(0,
3347+
abi.box_rc_field_body,
3348+
abi.closure_elt_target));
3349+
bcx = lltarget.bcx;
3350+
auto lltargetclosure = bcx.build.GEP(lltarget.val,
33533351
vec(C_int(0),
33543352
C_int(abi.fn_field_box)));
33553353
lltargetclosure = bcx.build.Load(lltargetclosure);
@@ -3370,10 +3368,13 @@ fn trans_bind_thunk(@crate_ctxt cx,
33703368
let uint i = 0u;
33713369
while (i < ty_param_count) {
33723370
auto lltyparam_ptr =
3373-
bcx.build.GEP(llbody, vec(C_int(0),
3374-
C_int(abi.closure_elt_ty_params),
3375-
C_int(i as int)));
3376-
llargs += vec(bcx.build.Load(lltyparam_ptr));
3371+
GEP_tup_like(bcx, closure_ty, llclosure,
3372+
vec(0,
3373+
abi.box_rc_field_body,
3374+
abi.closure_elt_ty_params,
3375+
(i as int)));
3376+
bcx = lltyparam_ptr.bcx;
3377+
llargs += vec(bcx.build.Load(lltyparam_ptr.val));
33773378
i += 1u;
33783379
}
33793380

@@ -3385,11 +3386,15 @@ fn trans_bind_thunk(@crate_ctxt cx,
33853386

33863387
// Arg provided at binding time; thunk copies it from closure.
33873388
case (some[@ast.expr](_)) {
3388-
let ValueRef bound_arg = bcx.build.GEP(llbound,
3389-
vec(C_int(0),
3390-
C_int(b)));
3389+
auto bound_arg =
3390+
GEP_tup_like(bcx, closure_ty, llclosure,
3391+
vec(0,
3392+
abi.box_rc_field_body,
3393+
abi.closure_elt_bindings,
3394+
b));
33913395
// FIXME: possibly support passing aliases someday.
3392-
llargs += bcx.build.Load(bound_arg);
3396+
bcx = bound_arg.bcx;
3397+
llargs += bcx.build.Load(bound_arg.val);
33933398
b += 1;
33943399
}
33953400

@@ -3412,7 +3417,7 @@ fn trans_bind_thunk(@crate_ctxt cx,
34123417
}
34133418

34143419
// FIXME: turn this call + ret into a tail call.
3415-
auto lltargetfn = bcx.build.GEP(lltarget,
3420+
auto lltargetfn = bcx.build.GEP(lltarget.val,
34163421
vec(C_int(0),
34173422
C_int(abi.fn_field_code)));
34183423
lltargetfn = bcx.build.Load(lltargetfn);
@@ -3479,21 +3484,26 @@ fn trans_bind(@block_ctxt cx, @ast.expr f,
34793484
i += 1u;
34803485
}
34813486

3482-
// Get the type of the bound function.
3483-
let TypeRef lltarget_ty = type_of(bcx.fcx.ccx, outgoing_fty);
3484-
34853487
// Synthesize a closure type.
34863488
let @ty.t bindings_ty = plain_ty(ty.ty_tup(bound_tys));
3487-
let TypeRef llbindings_ty = type_of(bcx.fcx.ccx, bindings_ty);
3488-
let TypeRef llclosure_ty = T_closure_ptr(cx.fcx.ccx.tn,
3489-
lltarget_ty,
3490-
llbindings_ty,
3491-
ty_param_count);
3492-
3493-
// Malloc a box for the body.
3494-
// FIXME: this isn't generic-safe
3495-
auto r = trans_raw_malloc(bcx, llclosure_ty,
3496-
llsize_of(llvm.LLVMGetElementType(llclosure_ty)));
3489+
3490+
// NB: keep this in sync with T_closure_ptr; we're making
3491+
// a ty.t structure that has the same "shape" as the LLVM type
3492+
// it constructs.
3493+
let @ty.t tydesc_ty = plain_ty(ty.ty_type);
3494+
3495+
let vec[@ty.t] captured_tys =
3496+
_vec.init_elt[@ty.t](tydesc_ty, ty_param_count);
3497+
3498+
let vec[@ty.t] closure_tys =
3499+
vec(tydesc_ty,
3500+
outgoing_fty,
3501+
bindings_ty,
3502+
plain_ty(ty.ty_tup(captured_tys)));
3503+
3504+
let @ty.t closure_ty = plain_ty(ty.ty_tup(closure_tys));
3505+
3506+
auto r = trans_malloc_boxed(bcx, closure_ty);
34973507
auto box = r.val;
34983508
bcx = r.bcx;
34993509
auto rc = bcx.build.GEP(box,
@@ -3561,9 +3571,10 @@ fn trans_bind(@block_ctxt cx, @ast.expr f,
35613571
C_int(abi.fn_field_code)));
35623572

35633573
let @ty.t pair_ty = node_ann_type(cx.fcx.ccx, ann);
3574+
35643575
let ValueRef llthunk =
35653576
trans_bind_thunk(cx.fcx.ccx, pair_ty, outgoing_fty,
3566-
args, llclosure_ty, bound_tys,
3577+
args, closure_ty, bound_tys,
35673578
ty_param_count);
35683579

35693580
bcx.build.Store(llthunk, pair_code);

src/test/run-pass/generic-bind.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ fn id[T](&T t) -> T {
33
}
44

55
fn main() {
6-
auto f = bind id[int](_);
7-
check (f(10) == 10);
6+
auto t = tup(1,2,3,4,5,6,7);
7+
check (t._5 == 6);
8+
// FIXME: this needs to work.
9+
// auto f0 = bind id[tup(int,int,int,int,int,int,int)](t);
10+
auto f1 = bind id[tup(int,int,int,int,int,int,int)](_);
11+
// check (f0()._5 == 6);
12+
check (f1(t)._5 == 6);
813
}

0 commit comments

Comments
 (0)