Skip to content

Commit 1f2585f

Browse files
committed
Teach trans to access object fields.
1 parent 9676fb2 commit 1f2585f

File tree

1 file changed

+100
-14
lines changed

1 file changed

+100
-14
lines changed

src/comp/middle/trans.rs

Lines changed: 100 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ state type crate_ctxt = rec(session.session sess,
6868
hashmap[ast.def_id, @ast.item] items,
6969
hashmap[ast.def_id, @tag_info] tags,
7070
hashmap[@ty.t, ValueRef] tydescs,
71+
vec[ast.obj_field] obj_fields,
7172
@glue_fns glues,
7273
namegen names,
7374
str path);
@@ -77,6 +78,7 @@ state type fn_ctxt = rec(ValueRef llfn,
7778
mutable option.t[ValueRef] llself,
7879
mutable option.t[ValueRef] llretptr,
7980
hashmap[ast.def_id, ValueRef] llargs,
81+
hashmap[ast.def_id, ValueRef] llobjfields,
8082
hashmap[ast.def_id, ValueRef] lllocals,
8183
hashmap[ast.def_id, ValueRef] lltydescs,
8284
@crate_ctxt ccx);
@@ -1667,6 +1669,10 @@ fn trans_name(@block_ctxt cx, &ast.name n, &option.t[ast.def] dopt)
16671669
check (cx.fcx.lllocals.contains_key(did));
16681670
ret lval_mem(cx, cx.fcx.lllocals.get(did));
16691671
}
1672+
case (ast.def_obj_field(?did)) {
1673+
check (cx.fcx.llobjfields.contains_key(did));
1674+
ret lval_mem(cx, cx.fcx.llobjfields.get(did));
1675+
}
16701676
case (ast.def_fn(?did)) {
16711677
check (cx.fcx.ccx.item_ids.contains_key(did));
16721678
ret lval_val(cx, cx.fcx.ccx.item_ids.get(did));
@@ -2382,15 +2388,17 @@ fn new_fn_ctxt(@crate_ctxt cx,
23822388

23832389
let ValueRef lltaskptr = llvm.LLVMGetParam(llfndecl, 0u);
23842390

2385-
let hashmap[ast.def_id, ValueRef] lllocals = new_def_hash[ValueRef]();
23862391
let hashmap[ast.def_id, ValueRef] llargs = new_def_hash[ValueRef]();
2392+
let hashmap[ast.def_id, ValueRef] llobjfields = new_def_hash[ValueRef]();
2393+
let hashmap[ast.def_id, ValueRef] lllocals = new_def_hash[ValueRef]();
23872394
let hashmap[ast.def_id, ValueRef] lltydescs = new_def_hash[ValueRef]();
23882395

23892396
ret @rec(llfn=llfndecl,
23902397
lltaskptr=lltaskptr,
23912398
mutable llself=none[ValueRef],
23922399
mutable llretptr=none[ValueRef],
23932400
llargs=llargs,
2401+
llobjfields=llobjfields,
23942402
lllocals=lllocals,
23952403
lltydescs=lltydescs,
23962404
ccx=cx);
@@ -2434,16 +2442,31 @@ fn create_llargs_for_fn_args(&@fn_ctxt cx,
24342442
}
24352443
}
24362444

2437-
24382445
// Recommended LLVM style, strange though this is, is to copy from args to
24392446
// allocas immediately upon entry; this permits us to GEP into structures we
24402447
// were passed and whatnot. Apparently mem2reg will mop up.
24412448

2442-
fn copy_args_to_allocas(@block_ctxt cx, vec[ast.arg] args,
2443-
vec[ty.arg] arg_tys) {
2449+
impure fn copy_args_to_allocas(@block_ctxt cx,
2450+
option.t[TypeRef] ty_self,
2451+
vec[ast.arg] args,
2452+
vec[ty.arg] arg_tys) {
24442453

24452454
let uint arg_n = 0u;
24462455

2456+
alt (cx.fcx.llself) {
2457+
case (some[ValueRef](?self_v)) {
2458+
alt (ty_self) {
2459+
case (some[TypeRef](?self_t)) {
2460+
auto alloca = cx.build.Alloca(self_t);
2461+
cx.build.Store(self_v, alloca);
2462+
cx.fcx.llself = some[ValueRef](alloca);
2463+
}
2464+
}
2465+
}
2466+
case (_) {
2467+
}
2468+
}
2469+
24472470
for (ast.arg aarg in args) {
24482471
if (aarg.mode != ast.alias) {
24492472
auto arg_t = type_of_arg(cx.fcx.ccx, arg_tys.(arg_n));
@@ -2481,19 +2504,66 @@ fn ret_ty_of_fn(ast.ann ann) -> @ty.t {
24812504
fail;
24822505
}
24832506

2507+
fn create_llobjfields_for_fields(@block_ctxt cx, ValueRef llself) {
2508+
2509+
let vec[TypeRef] llfield_tys = vec();
2510+
2511+
for (ast.obj_field f in cx.fcx.ccx.obj_fields) {
2512+
llfield_tys += node_type(cx.fcx.ccx, f.ann);
2513+
}
2514+
2515+
let TypeRef llfields_ty = T_struct(llfield_tys);
2516+
let TypeRef lltydesc_ty = T_ptr(T_tydesc());
2517+
let TypeRef llobj_body_ty = T_struct(vec(lltydesc_ty,
2518+
llfields_ty));
2519+
let TypeRef llobj_box_ty = T_ptr(T_box(llobj_body_ty));
2520+
2521+
auto box_cell =
2522+
cx.build.GEP(llself,
2523+
vec(C_int(0),
2524+
C_int(abi.obj_field_box)));
2525+
2526+
auto box_ptr = cx.build.Load(box_cell);
2527+
2528+
box_ptr = cx.build.PointerCast(box_ptr, llobj_box_ty);
2529+
2530+
auto obj_fields = cx.build.GEP(box_ptr,
2531+
vec(C_int(0),
2532+
C_int(abi.box_rc_field_body),
2533+
C_int(abi.obj_body_elt_fields)));
2534+
2535+
let int i = 0;
2536+
for (ast.obj_field f in cx.fcx.ccx.obj_fields) {
2537+
let ValueRef llfield = cx.build.GEP(obj_fields,
2538+
vec(C_int(0),
2539+
C_int(i)));
2540+
cx.fcx.llobjfields.insert(f.id, llfield);
2541+
i += 1;
2542+
}
2543+
}
2544+
24842545
impure fn trans_fn(@crate_ctxt cx, &ast._fn f, ast.def_id fid,
2546+
option.t[TypeRef] ty_self,
24852547
&vec[ast.ty_param] ty_params, &ast.ann ann) {
24862548

24872549
auto llfndecl = cx.item_ids.get(fid);
24882550
cx.item_names.insert(cx.path, llfndecl);
24892551

24902552
auto fcx = new_fn_ctxt(cx, cx.path, llfndecl);
2491-
create_llargs_for_fn_args(fcx, none[TypeRef], ret_ty_of_fn(ann),
2553+
create_llargs_for_fn_args(fcx, ty_self, ret_ty_of_fn(ann),
24922554
f.inputs, ty_params);
2493-
24942555
auto bcx = new_top_block_ctxt(fcx);
24952556

2496-
copy_args_to_allocas(bcx, f.inputs, arg_tys_of_fn(ann));
2557+
copy_args_to_allocas(bcx, ty_self, f.inputs,
2558+
arg_tys_of_fn(ann));
2559+
2560+
alt (fcx.llself) {
2561+
case (some[ValueRef](?llself)) {
2562+
create_llobjfields_for_fields(bcx, llself);
2563+
}
2564+
case (_) {
2565+
}
2566+
}
24972567

24982568
auto res = trans_block(bcx, f.body);
24992569
if (!is_terminated(res.bcx)) {
@@ -2507,7 +2577,15 @@ impure fn trans_vtbl(@crate_ctxt cx, TypeRef self_ty,
25072577
&ast._obj ob,
25082578
&vec[ast.ty_param] ty_params) -> ValueRef {
25092579
let vec[ValueRef] methods = vec();
2510-
for (@ast.method m in ob.methods) {
2580+
2581+
fn meth_lteq(&@ast.method a, &@ast.method b) -> bool {
2582+
ret _str.lteq(a.node.ident, b.node.ident);
2583+
}
2584+
2585+
auto meths = std.sort.merge_sort[@ast.method](bind meth_lteq(_,_),
2586+
ob.methods);
2587+
2588+
for (@ast.method m in meths) {
25112589

25122590
auto llfnty = T_nil();
25132591
alt (node_ann_type(cx, m.node.ann).struct) {
@@ -2518,11 +2596,15 @@ impure fn trans_vtbl(@crate_ctxt cx, TypeRef self_ty,
25182596
}
25192597
}
25202598

2521-
let str s = cx.names.next("_rust_method") + "." + cx.path;
2599+
let @crate_ctxt mcx = @rec(path=cx.path + "." + m.node.ident
2600+
with *cx);
2601+
2602+
let str s = cx.names.next("_rust_method") + "." + mcx.path;
25222603
let ValueRef llfn = decl_fastcall_fn(cx.llmod, s, llfnty);
25232604
cx.item_ids.insert(m.node.id, llfn);
25242605

2525-
trans_fn(cx, m.node.meth, m.node.id, ty_params, m.node.ann);
2606+
trans_fn(mcx, m.node.meth, m.node.id, some[TypeRef](self_ty),
2607+
ty_params, m.node.ann);
25262608
methods += llfn;
25272609
}
25282610
auto vtbl = C_struct(methods);
@@ -2556,7 +2638,7 @@ impure fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
25562638
auto bcx = new_top_block_ctxt(fcx);
25572639

25582640
let vec[ty.arg] arg_tys = arg_tys_of_fn(ann);
2559-
copy_args_to_allocas(bcx, fn_args, arg_tys);
2641+
copy_args_to_allocas(bcx, none[TypeRef], fn_args, arg_tys);
25602642

25612643
auto llself_ty = type_of(cx, ret_ty_of_fn(ann));
25622644
auto pair = bcx.build.Alloca(llself_ty);
@@ -2664,7 +2746,7 @@ fn trans_tag_variant(@crate_ctxt cx, ast.def_id tag_id,
26642746
auto bcx = new_top_block_ctxt(fcx);
26652747

26662748
auto arg_tys = arg_tys_of_fn(variant.ann);
2667-
copy_args_to_allocas(bcx, fn_args, arg_tys);
2749+
copy_args_to_allocas(bcx, none[TypeRef], fn_args, arg_tys);
26682750

26692751
auto info = cx.tags.get(tag_id);
26702752

@@ -2707,10 +2789,11 @@ impure fn trans_item(@crate_ctxt cx, &ast.item item) {
27072789
alt (item.node) {
27082790
case (ast.item_fn(?name, ?f, ?tps, ?fid, ?ann)) {
27092791
auto sub_cx = @rec(path=cx.path + "." + name with *cx);
2710-
trans_fn(sub_cx, f, fid, tps, ann);
2792+
trans_fn(sub_cx, f, fid, none[TypeRef], tps, ann);
27112793
}
27122794
case (ast.item_obj(?name, ?ob, ?tps, ?oid, ?ann)) {
2713-
auto sub_cx = @rec(path=cx.path + "." + name with *cx);
2795+
auto sub_cx = @rec(path=cx.path + "." + name,
2796+
obj_fields=ob.fields with *cx);
27142797
trans_obj(sub_cx, ob, oid, tps, ann);
27152798
}
27162799
case (ast.item_mod(?name, ?m, _)) {
@@ -2927,6 +3010,7 @@ fn trans_exit_task_glue(@crate_ctxt cx) {
29273010
mutable llself=none[ValueRef],
29283011
mutable llretptr=none[ValueRef],
29293012
llargs=new_def_hash[ValueRef](),
3013+
llobjfields=new_def_hash[ValueRef](),
29303014
lllocals=new_def_hash[ValueRef](),
29313015
lltydescs=new_def_hash[ValueRef](),
29323016
ccx=cx);
@@ -3097,6 +3181,7 @@ fn trans_crate(session.session sess, @ast.crate crate, str output,
30973181
auto hasher = ty.hash_ty;
30983182
auto eqer = ty.eq_ty;
30993183
auto tydescs = map.mk_hashmap[@ty.t,ValueRef](hasher, eqer);
3184+
let vec[ast.obj_field] obj_fields = vec();
31003185

31013186
auto cx = @rec(sess = sess,
31023187
llmod = llmod,
@@ -3108,6 +3193,7 @@ fn trans_crate(session.session sess, @ast.crate crate, str output,
31083193
items = new_def_hash[@ast.item](),
31093194
tags = new_def_hash[@tag_info](),
31103195
tydescs = tydescs,
3196+
obj_fields = obj_fields,
31113197
glues = glues,
31123198
names = namegen(0),
31133199
path = "_rust");

0 commit comments

Comments
 (0)