@@ -103,28 +103,18 @@ fn trans_obj(cx: @local_ctxt, sp: &span, ob: &ast::_obj,
103
103
// Store null into pair, if no args or typarams.
104
104
bcx. build . Store ( C_null ( llbox_ty) , pair_box) ;
105
105
} else {
106
- // Otherwise, we have to synthesize a big structural type for the
107
- // object body.
108
106
let obj_fields: [ ty:: t ] = ~[ ] ;
109
107
for a: ty:: arg in arg_tys { obj_fields += ~[ a. ty ] ; }
110
108
111
- // Tuple type for fields: [field, ...]
112
- let fields_ty: ty:: t = ty:: mk_imm_tup ( ccx. tcx , obj_fields) ;
113
-
114
- let tydesc_ty = ty:: mk_type ( ccx. tcx ) ;
115
109
let tps: [ ty:: t ] = ~[ ] ;
110
+ let tydesc_ty = ty:: mk_type ( ccx. tcx ) ;
116
111
for tp: ast:: ty_param in ty_params { tps += ~[ tydesc_ty] ; }
117
112
118
- // Tuple type for typarams: [typaram, ...]
119
- let typarams_ty: ty:: t = ty:: mk_imm_tup ( ccx. tcx , tps) ;
120
-
121
- // Tuple type for body:
122
- // [tydesc_ty, [typaram, ...], [field, ...]]
123
- let body_ty: ty:: t =
124
- ty:: mk_imm_tup ( ccx. tcx , ~[ tydesc_ty, typarams_ty, fields_ty] ) ;
125
-
126
- // Hand this type we've synthesized off to trans_malloc_boxed, which
127
- // allocates a box, including space for a refcount.
113
+ // Synthesize an object body type and hand it off to
114
+ // trans_malloc_boxed, which allocates a box, including space for a
115
+ // refcount.
116
+ let body_ty: ty:: t = create_object_body_type ( ccx. tcx , obj_fields, tps,
117
+ none) ;
128
118
let box = trans_malloc_boxed ( bcx, body_ty) ;
129
119
bcx = box. bcx ;
130
120
let body = box. body ;
@@ -161,6 +151,8 @@ fn trans_obj(cx: @local_ctxt, sp: &span, ob: &ast::_obj,
161
151
GEP_tup_like ( bcx, body_ty, body,
162
152
~[ 0 , abi:: obj_body_elt_typarams] ) ;
163
153
bcx = body_typarams. bcx ;
154
+ // TODO: can we just get typarams_ty out of body_ty instead?
155
+ let typarams_ty: ty:: t = ty:: mk_imm_tup ( ccx. tcx , tps) ;
164
156
let i: int = 0 ;
165
157
for tp: ast:: ty_param in ty_params {
166
158
let typaram = bcx. fcx . lltydescs . ( i) ;
@@ -181,6 +173,8 @@ fn trans_obj(cx: @local_ctxt, sp: &span, ob: &ast::_obj,
181
173
alt bcx. fcx . llargs . find ( f. id ) {
182
174
some ( arg1) {
183
175
let arg = load_if_immediate ( bcx, arg1, arg_tys. ( i) . ty ) ;
176
+ // TODO: can we just get fields_ty out of body_ty instead?
177
+ let fields_ty: ty:: t = ty:: mk_imm_tup ( ccx. tcx , obj_fields) ;
184
178
let field =
185
179
GEP_tup_like ( bcx, fields_ty, body_fields. val , ~[ 0 , i] ) ;
186
180
bcx = field. bcx ;
@@ -303,30 +297,19 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: &span, anon_obj: &ast::anon_obj,
303
297
304
298
if std:: ivec:: len[ ast:: anon_obj_field] ( additional_fields) == 0 u &&
305
299
anon_obj. inner_obj == none {
300
+
306
301
// If the object we're translating has no fields and no inner_obj,
307
302
// there's not much to do.
308
303
bcx. build . Store ( C_null ( llbox_ty) , pair_box) ;
309
- } else {
310
-
311
- // Synthesize a tuple type for fields: [field, ...]
312
- let fields_ty: ty:: t = ty:: mk_imm_tup ( ccx. tcx , additional_field_tys) ;
313
-
314
- // Type for tydescs.
315
- let tydesc_ty: ty:: t = ty:: mk_type ( ccx. tcx ) ;
316
-
317
- // Placeholder for non-existent typarams, since anon objs don't have
318
- // them.
319
- let typarams_ty: ty:: t = ty:: mk_imm_tup ( ccx. tcx , ~[ ] ) ;
320
304
321
- // Tuple type for body:
322
- // [tydesc, [typaram, ...], [field, ...], inner_obj]
323
- let body_ty: ty:: t =
324
- ty:: mk_imm_tup ( ccx. tcx ,
325
- ~[ tydesc_ty, typarams_ty, fields_ty,
326
- inner_obj_ty] ) ;
305
+ } else {
327
306
328
- // Hand this type we've synthesized off to trans_malloc_boxed, which
329
- // allocates a box, including space for a refcount.
307
+ // Synthesize a type for the object body and hand it off to
308
+ // trans_malloc_boxed, which allocates a box, including space for a
309
+ // refcount.
310
+ let body_ty: ty:: t = create_object_body_type ( ccx. tcx ,
311
+ additional_field_tys,
312
+ ~[ ] , some ( inner_obj_ty) ) ;
330
313
let box = trans_malloc_boxed ( bcx, body_ty) ;
331
314
bcx = box. bcx ;
332
315
let body = box. body ;
@@ -364,7 +347,8 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: &span, anon_obj: &ast::anon_obj,
364
347
// have additional field exprs in the AST.
365
348
load_if_immediate ( bcx, additional_field_vals. ( i) . val ,
366
349
additional_field_tys. ( i) ) ;
367
-
350
+ let fields_ty: ty:: t = ty:: mk_imm_tup ( ccx. tcx ,
351
+ additional_field_tys) ;
368
352
let field =
369
353
GEP_tup_like ( bcx, fields_ty, body_fields. val , ~[ 0 , i] ) ;
370
354
bcx = field. bcx ;
@@ -806,25 +790,9 @@ fn process_fwding_mthd(cx: @local_ctxt, sp: &span, m: @ty::method,
806
790
807
791
// Now, we need to figure out exactly what type the body is supposed to be
808
792
// cast to.
809
-
810
- // NB: This next part is almost flat-out copypasta from trans_anon_obj.
811
- // It would be great to factor this out.
812
-
813
- // Synthesize a tuple type for fields: [field, ...]
814
- let fields_ty: ty:: t = ty:: mk_imm_tup ( cx. ccx . tcx , additional_field_tys) ;
815
-
816
- // Type for tydescs.
817
- let tydesc_ty: ty:: t = ty:: mk_type ( cx. ccx . tcx ) ;
818
-
819
- // Placeholder for non-existent typarams, since anon objs don't have them.
820
- let typarams_ty: ty:: t = ty:: mk_imm_tup ( cx. ccx . tcx , ~[ ] ) ;
821
-
822
- // Tuple type for body: [tydesc, [typaram, ...], [field, ...], inner_obj]
823
-
824
- let body_ty: ty:: t =
825
- ty:: mk_imm_tup ( cx. ccx . tcx ,
826
- ~[ tydesc_ty, typarams_ty, fields_ty, inner_obj_ty] ) ;
827
-
793
+ let body_ty: ty:: t = create_object_body_type ( cx. ccx . tcx ,
794
+ additional_field_tys, ~[ ] ,
795
+ some ( inner_obj_ty) ) ;
828
796
// And cast to that type.
829
797
llself_obj_body =
830
798
bcx. build . PointerCast ( llself_obj_body,
@@ -920,6 +888,31 @@ fn process_fwding_mthd(cx: @local_ctxt, sp: &span, m: @ty::method,
920
888
ret llforwarding_fn;
921
889
}
922
890
891
+ // create_object_body_type: Synthesize a big structural tuple type for an
892
+ // object body: [tydesc, [typaram, ...], [field, ...], inner_obj].
893
+ fn create_object_body_type ( tcx : & ty:: ctxt , fields_ty : & [ ty:: t ] ,
894
+ typarams_ty : & [ ty:: t ] ,
895
+ maybe_inner_obj_ty : option:: t [ ty:: t ] ) -> ty:: t {
896
+
897
+ let tydesc_ty: ty:: t = ty:: mk_type ( tcx) ;
898
+ let typarams_ty_tup: ty:: t = ty:: mk_imm_tup ( tcx, typarams_ty) ;
899
+ let fields_ty_tup: ty:: t = ty:: mk_imm_tup ( tcx, fields_ty) ;
900
+
901
+ let body_ty: ty:: t ;
902
+ alt maybe_inner_obj_ty {
903
+ some( inner_obj_ty) {
904
+ body_ty = ty:: mk_imm_tup ( tcx, ~[ tydesc_ty, typarams_ty_tup,
905
+ fields_ty_tup, inner_obj_ty] ) ;
906
+ }
907
+ none {
908
+ body_ty = ty:: mk_imm_tup ( tcx, ~[ tydesc_ty, typarams_ty_tup,
909
+ fields_ty_tup] ) ;
910
+ }
911
+ }
912
+
913
+ ret body_ty;
914
+ }
915
+
923
916
// process_normal_mthd: Create the contents of a normal vtable slot. A helper
924
917
// function for create_vtbl.
925
918
fn process_normal_mthd ( cx : @local_ctxt , m : @ast:: method , self_ty : ty:: t ,
0 commit comments