Skip to content

Commit 007af36

Browse files
committed
Comments, cleanup, whitespace, refactoring.
1 parent b23360e commit 007af36

File tree

1 file changed

+74
-77
lines changed

1 file changed

+74
-77
lines changed

src/comp/middle/trans_objects.rs

Lines changed: 74 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -23,26 +23,26 @@ import trans::*;
2323
export trans_anon_obj;
2424
export trans_obj;
2525

26-
// trans_obj: creates an LLVM function that is the object constructor for the
26+
// trans_obj: create an LLVM function that is the object constructor for the
2727
// object being translated.
2828
fn trans_obj(cx: @local_ctxt, sp: &span, ob: &ast::_obj,
2929
ctor_id: ast::node_id, ty_params: &[ast::ty_param]) {
30+
3031
// To make a function, we have to create a function context and, inside
3132
// that, a number of block contexts for which code is generated.
32-
3333
let ccx = cx.ccx;
3434
let llctor_decl;
3535
alt ccx.item_ids.find(ctor_id) {
3636
some(x) { llctor_decl = x; }
3737
_ { cx.ccx.sess.span_fatal(sp, "unbound llctor_decl in trans_obj"); }
3838
}
39+
3940
// Much like trans_fn, we must create an LLVM function, but since we're
4041
// starting with an ast::_obj rather than an ast::_fn, we have some setup
4142
// work to do.
4243

4344
// The fields of our object will become the arguments to the function
4445
// we're creating.
45-
4646
let fn_args: [ast::arg] = ~[];
4747
for f: ast::obj_field in ob.fields {
4848
fn_args +=
@@ -93,10 +93,6 @@ fn trans_obj(cx: @local_ctxt, sp: &span, ob: &ast::_obj,
9393
// Next we have to take care of the other half of the pair we're
9494
// returning: a boxed (reference-counted) tuple containing a tydesc,
9595
// typarams, and fields.
96-
97-
// FIXME: What about inner_obj? Do we have to think about it here?
98-
// (Pertains to issues #538/#539/#540/#543.)
99-
10096
let llbox_ty: TypeRef = T_ptr(T_empty_struct());
10197

10298
if std::ivec::len[ast::ty_param](ty_params) == 0u &&
@@ -122,7 +118,8 @@ fn trans_obj(cx: @local_ctxt, sp: &span, ob: &ast::_obj,
122118
// Tuple type for typarams: [typaram, ...]
123119
let typarams_ty: ty::t = ty::mk_imm_tup(ccx.tcx, tps);
124120

125-
// Tuple type for body: [tydesc_ty, [typaram, ...], [field, ...]]
121+
// Tuple type for body:
122+
// [tydesc_ty, [typaram, ...], [field, ...]]
126123
let body_ty: ty::t =
127124
ty::mk_imm_tup(ccx.tcx, ~[tydesc_ty, typarams_ty, fields_ty]);
128125

@@ -215,12 +212,10 @@ fn trans_obj(cx: @local_ctxt, sp: &span, ob: &ast::_obj,
215212
fn trans_anon_obj(bcx: @block_ctxt, sp: &span, anon_obj: &ast::anon_obj,
216213
id: ast::node_id) -> result {
217214

218-
219215
let ccx = bcx_ccx(bcx);
220216

221-
// Fields.
222-
// FIXME (part of issue #538): Where do we fill in the field *values* from
223-
// the outer object?
217+
// Fields. FIXME (part of issue #538): Where do we fill in the field
218+
// *values* from the outer object?
224219
let additional_fields: [ast::anon_obj_field] = ~[];
225220
let additional_field_vals: [result] = ~[];
226221
let additional_field_tys: [ty::t] = ~[];
@@ -254,32 +249,31 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: &span, anon_obj: &ast::anon_obj,
254249
let vtbl;
255250
alt anon_obj.inner_obj {
256251
none. {
257-
// We need a dummy inner_obj_ty for setting up the object body
258-
// later.
252+
// We need a dummy inner_obj_ty for setting up the object body later.
259253
inner_obj_ty = ty::mk_type(ccx.tcx);
260254

261-
// If there's no inner_obj -- that is, if we're just adding new
262-
// fields rather than extending an existing object -- then we just
263-
// pass the outer object to create_vtbl(). Our vtable won't need
255+
// If there's no inner_obj -- that is, if we're creating a new object
256+
// from nothing rather than extending an existing object -- then we
257+
// just pass the outer object to create_vtbl(). Our vtable won't need
264258
// to have any forwarding slots.
265259
vtbl =
266260
create_vtbl(bcx.fcx.lcx, sp, outer_obj_ty, wrapper_obj, ~[], none,
267261
additional_field_tys);
268262
}
269263
some(e) {
270-
// TODO: What makes more sense to get the type of an expr --
271-
// calling ty::expr_ty(ccx.tcx, e) on it or calling
264+
// TODO: What makes more sense to get the type of an expr -- calling
265+
// ty::expr_ty(ccx.tcx, e) on it or calling
272266
// ty::node_id_to_type(ccx.tcx, id) on its id?
273267
inner_obj_ty = ty::expr_ty(ccx.tcx, e);
274268
//inner_obj_ty = ty::node_id_to_type(ccx.tcx, e.id);
275269

276270
// If there's a inner_obj, we pass its type along to create_vtbl().
277-
// Part of what create_vtbl() will do is take the set difference
278-
// of methods defined on the original and methods being added.
279-
// For every method defined on the original that does *not* have
280-
// one with a matching name and type being added, we'll need to
281-
// create a forwarding slot. And, of course, we need to create a
282-
// normal vtable entry for every method being added.
271+
// Part of what create_vtbl() will do is take the set difference of
272+
// methods defined on the original and methods being added. For every
273+
// method defined on the original that does *not* have one with a
274+
// matching name and type being added, we'll need to create a
275+
// forwarding slot. And, of course, we need to create a normal vtable
276+
// entry for every method being added.
283277
vtbl =
284278
create_vtbl(bcx.fcx.lcx, sp, outer_obj_ty, wrapper_obj, ~[],
285279
some(inner_obj_ty), additional_field_tys);
@@ -294,8 +288,6 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: &span, anon_obj: &ast::anon_obj,
294288
add_clean_temp(bcx, pair, t);
295289

296290
// Grab onto the first and second elements of the pair.
297-
// abi::obj_field_vtbl and abi::obj_field_box simply specify words 0 and 1
298-
// of 'pair'.
299291
let pair_vtbl =
300292
bcx.build.GEP(pair, ~[C_int(0), C_int(abi::obj_field_vtbl)]);
301293
let pair_box =
@@ -414,8 +406,8 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: &span, anon_obj: &ast::anon_obj,
414406
// Used only inside create_vtbl and create_backwarding_vtbl to distinguish
415407
// different kinds of slots we'll have to create.
416408
tag vtbl_mthd {
417-
// Normal methods are complete AST nodes, but for forwarding methods,
418-
// the only information we'll have about them is their type.
409+
// Normal methods are complete AST nodes, but for forwarding methods, the
410+
// only information we'll have about them is their type.
419411
normal_mthd(@ast::method);
420412
fwding_mthd(@ty::method);
421413
}
@@ -443,8 +435,8 @@ fn vtbl_mthd_lteq(a: &vtbl_mthd, b: &vtbl_mthd) -> bool {
443435
}
444436
}
445437

446-
// Used by create_vtbl to filter a list of methods to remove the ones that we
447-
// don't need forwarding slots for.
438+
// filtering_fn: Used by create_vtbl to filter a list of methods to remove the
439+
// ones that we don't need forwarding slots for.
448440
fn filtering_fn(cx: @local_ctxt, m: &vtbl_mthd,
449441
addtl_meths: [@ast::method]) ->
450442
option::t[vtbl_mthd] {
@@ -468,8 +460,8 @@ fn filtering_fn(cx: @local_ctxt, m: &vtbl_mthd,
468460
}
469461
}
470462

471-
// Create a vtable for an object being translated. Returns a pointer into
472-
// read-only memory.
463+
// create_vtbl: Create a vtable for a regular object or for an outer anonymous
464+
// object, and return a pointer to it.
473465
fn create_vtbl(cx: @local_ctxt, sp: &span, outer_obj_ty: ty::t,
474466
ob: &ast::_obj, ty_params: &[ast::ty_param],
475467
inner_obj_ty: option::t[ty::t],
@@ -479,6 +471,9 @@ fn create_vtbl(cx: @local_ctxt, sp: &span, outer_obj_ty: ty::t,
479471

480472
alt inner_obj_ty {
481473
none. {
474+
// We're creating a vtable for a regular object, or for an anonymous
475+
// object that doesn't extend an existing one.
476+
482477
// Sort and process all the methods.
483478
let meths =
484479
std::sort::ivector::merge_sort[@ast::method]
@@ -490,24 +485,18 @@ fn create_vtbl(cx: @local_ctxt, sp: &span, outer_obj_ty: ty::t,
490485
}
491486
}
492487
some(inner_obj_ty) {
493-
// If this vtable is being created for an extended object, then the
494-
// vtable needs to contain 'forwarding slots' for methods that were on
495-
// the original object and are not being overridden by the extended
496-
// one. So, to find the set of methods that we need forwarding slots
497-
// for, we need to take the set difference of inner_obj_methods
498-
// (methods on the original object) and ob.methods (methods being
499-
// added, whether entirely new or overriding).
500-
501-
// inner_obj_ty is the type of the inner object being forwarded to,
502-
// and "ob" is the wrapper object. We need to take apart
503-
// inner_obj_ty, which is the type of the object being forwarded to
504-
// (it had better have an object type with methods!) and put those
505-
// original methods onto the list of methods we need forwarding
506-
// methods for.
488+
// We're creating a vtable for an anonymous object that extends an
489+
// existing one.
490+
491+
// The vtable needs to contain 'forwarding slots' for any methods that
492+
// were on the inner object and are not being overridden by the outer
493+
// one. To find the set of methods that we need forwarding slots for,
494+
// we take the set difference of { methods on the original object }
495+
// and { methods being added, whether entirely new or overriding }.
507496

508497
let meths: [vtbl_mthd] = ~[];
509498

510-
// Gather up methods on the original object in 'meths'.
499+
// Gather up methods on the inner object.
511500
alt ty::struct(cx.ccx.tcx, inner_obj_ty) {
512501
ty::ty_obj(inner_obj_methods) {
513502
for m: ty::method in inner_obj_methods {
@@ -520,8 +509,8 @@ fn create_vtbl(cx: @local_ctxt, sp: &span, outer_obj_ty: ty::t,
520509
}
521510
}
522511

523-
// Now, filter out any methods that we don't need forwarding slots
524-
// for, because they're being overridden.
512+
// Filter out any methods that we don't need forwarding slots for
513+
// because they're being overridden.
525514
let f = bind filtering_fn(cx, _, ob.methods);
526515
meths = std::ivec::filter_map[vtbl_mthd, vtbl_mthd](f, meths);
527516

@@ -534,6 +523,8 @@ fn create_vtbl(cx: @local_ctxt, sp: &span, outer_obj_ty: ty::t,
534523
std::sort::ivector::merge_sort[vtbl_mthd]
535524
(bind vtbl_mthd_lteq(_, _), meths);
536525

526+
// To create forwarding methods, we'll need a "backwarding" vtbl. See
527+
// create_backwarding_vtbl and process_bkwding_method for details.
537528
let backwarding_vtbl: ValueRef =
538529
create_backwarding_vtbl(cx, sp, inner_obj_ty, outer_obj_ty);
539530

@@ -554,17 +545,12 @@ fn create_vtbl(cx: @local_ctxt, sp: &span, outer_obj_ty: ty::t,
554545
}
555546
}
556547

557-
let vtbl = C_struct(llmethods);
558-
let vtbl_name = mangle_internal_name_by_path(cx.ccx, cx.path + ~["vtbl"]);
559-
let gvar =
560-
llvm::LLVMAddGlobal(cx.ccx.llmod, val_ty(vtbl), str::buf(vtbl_name));
561-
llvm::LLVMSetInitializer(gvar, vtbl);
562-
llvm::LLVMSetGlobalConstant(gvar, True);
563-
llvm::LLVMSetLinkage(gvar,
564-
lib::llvm::LLVMInternalLinkage as llvm::Linkage);
565-
ret gvar;
548+
ret finish_vtbl(cx, llmethods, "vtbl");
566549
}
567550

551+
// create_backwarding_vtbl: Create a vtable for the inner object of an
552+
// anonymous object, so that any self-calls made from the inner object's
553+
// methods get redirected appropriately.
568554
fn create_backwarding_vtbl(cx: @local_ctxt, sp: &span, inner_obj_ty: ty::t,
569555
outer_obj_ty: ty::t) -> ValueRef {
570556

@@ -591,28 +577,30 @@ fn create_backwarding_vtbl(cx: @local_ctxt, sp: &span, inner_obj_ty: ty::t,
591577

592578
// Methods should have already been sorted, so no need to do so again.
593579
for m: ty::method in meths {
594-
// We pass outer_obj_ty to process_fwding_mthd() because it's
595-
// the one being forwarded to.
580+
// We pass outer_obj_ty to process_fwding_mthd() because it's the one
581+
// being forwarded to.
596582
llmethods += ~[process_bkwding_mthd(
597583
cx, sp, @m, ~[], outer_obj_ty, ~[])];
598584
}
599585

586+
ret finish_vtbl(cx, llmethods, "backwarding_vtbl");
587+
}
588+
589+
// finish_vtbl: Given a vector of vtable entries, create the table in
590+
// read-only memory and return a pointer to it.
591+
fn finish_vtbl(cx: @local_ctxt, llmethods: [ValueRef], name: str)
592+
-> ValueRef {
600593
let vtbl = C_struct(llmethods);
601-
let vtbl_name =
602-
mangle_internal_name_by_path(cx.ccx,
603-
cx.path + ~["backwarding_vtbl"]);
594+
let vtbl_name = mangle_internal_name_by_path(cx.ccx, cx.path + ~[name]);
604595
let gvar =
605596
llvm::LLVMAddGlobal(cx.ccx.llmod, val_ty(vtbl), str::buf(vtbl_name));
606597
llvm::LLVMSetInitializer(gvar, vtbl);
607598
llvm::LLVMSetGlobalConstant(gvar, True);
608599
llvm::LLVMSetLinkage(gvar,
609600
lib::llvm::LLVMInternalLinkage as llvm::Linkage);
610-
611601
ret gvar;
612-
613602
}
614603

615-
616604
// process_bkwding_mthd: Create the backwarding function that appears in a
617605
// backwarding vtable slot.
618606
//
@@ -653,9 +641,9 @@ fn process_bkwding_mthd(cx: @local_ctxt, sp: &span, m: @ty::method,
653641
let bcx = new_top_block_ctxt(fcx);
654642
let lltop = bcx.llbb;
655643

656-
// The self-object will arrive in the backwarding function via the llenv
657-
// argument, but we need to jump past the first item in the self-stack to
658-
// get to the one we really want.
644+
// The self-object will arrive in the backwarding function via the
645+
// llenv argument, but we need to jump past the first item in the
646+
// self-stack to get to the one we really want.
659647

660648
// Cast to self-stack's type.
661649
let llenv = bcx.build.PointerCast(
@@ -717,8 +705,8 @@ fn process_bkwding_mthd(cx: @local_ctxt, sp: &span, m: @ty::method,
717705
bcx.build.PointerCast(llouter_mthd, T_ptr(T_ptr(llouter_mthd_ty)));
718706
llouter_mthd = bcx.build.Load(llouter_mthd);
719707

720-
// Set up the three implicit arguments to the outer method we'll need
721-
// to call.
708+
// Set up the three implicit arguments to the outer method we'll need to
709+
// call.
722710
let self_arg = llself_obj_ptr;
723711
let llouter_mthd_args: [ValueRef] = ~[llretptr, fcx.lltaskptr, self_arg];
724712

@@ -831,8 +819,7 @@ fn process_fwding_mthd(cx: @local_ctxt, sp: &span, m: @ty::method,
831819
// Placeholder for non-existent typarams, since anon objs don't have them.
832820
let typarams_ty: ty::t = ty::mk_imm_tup(cx.ccx.tcx, ~[]);
833821

834-
// Tuple type for body:
835-
// [tydesc, [typaram, ...], [field, ...], inner_obj]
822+
// Tuple type for body: [tydesc, [typaram, ...], [field, ...], inner_obj]
836823

837824
let body_ty: ty::t =
838825
ty::mk_imm_tup(cx.ccx.tcx,
@@ -951,9 +938,9 @@ fn process_normal_mthd(cx: @local_ctxt, m: @ast::method, self_ty: ty::t,
951938
let s: str = mangle_internal_name_by_path(mcx.ccx, mcx.path);
952939
let llfn: ValueRef = decl_internal_fastcall_fn(cx.ccx.llmod, s, llfnty);
953940

954-
// Every method on an object gets its node_id inserted into the
955-
// crate-wide item_ids map, together with the ValueRef that points to
956-
// where that method's definition will be in the executable.
941+
// Every method on an object gets its node_id inserted into the crate-wide
942+
// item_ids map, together with the ValueRef that points to where that
943+
// method's definition will be in the executable.
957944
cx.ccx.item_ids.insert(m.node.id, llfn);
958945
cx.ccx.item_symbols.insert(m.node.id, s);
959946
trans_fn(mcx, m.span, m.node.meth, llfn, some(self_ty), ty_params,
@@ -999,3 +986,13 @@ fn populate_self_stack(bcx: @block_ctxt,
999986

1000987
ret self_stack;
1001988
}
989+
//
990+
// Local Variables:
991+
// mode: rust
992+
// fill-column: 78;
993+
// indent-tabs-mode: nil
994+
// c-basic-offset: 4
995+
// buffer-file-coding-system: utf-8-unix
996+
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
997+
// End:
998+
//

0 commit comments

Comments
 (0)