@@ -414,14 +414,26 @@ fn llalign_of(cx: @crate_ctxt, t: TypeRef) -> ValueRef {
414
414
False ) ;
415
415
}
416
416
417
- fn size_of ( cx : @block_ctxt , t : ty:: t ) -> result {
418
- let { bcx, sz, align} = metrics ( cx, t, none) ;
419
- rslt ( bcx, align)
417
+ fn size_of ( bcx : @block_ctxt , t : ty:: t ) -> result {
418
+ assert !ty:: type_has_opaque_size ( bcx_tcx ( bcx) , t) ;
419
+ let { bcx, sz, align: _ } = metrics ( bcx, t, none) ;
420
+ rslt ( bcx, sz)
420
421
}
421
422
422
- fn align_of ( cx : @block_ctxt , t : ty:: t ) -> result {
423
- let { bcx, sz, align} = metrics ( cx, t, none) ;
424
- rslt ( bcx, align)
423
+ fn align_of ( bcx : @block_ctxt , t : ty:: t ) -> result {
424
+ assert !ty:: type_has_opaque_size ( bcx_tcx ( bcx) , t) ;
425
+ alt ty:: struct ( ccx. tcx , t) {
426
+ ty:: ty_opaque_closure. {
427
+ // Hack: the alignment of an opaque closure is always defined as the
428
+ // alignment of a pointer. This is not, however, strictly correct,
429
+ // depending on your point of view.
430
+ llalign_of ( bcx, T_ptr ( T_i8 ( ) ) ) ;
431
+ }
432
+ _ {
433
+ let { bcx, sz : _, align} = metrics ( bcx, t, none) ;
434
+ rslt ( bcx, align)
435
+ }
436
+ }
425
437
}
426
438
427
439
// Computes the size/alignment of the type `t`. `opt_v`, if provided, should
@@ -431,11 +443,13 @@ fn align_of(cx: @block_ctxt, t: ty::t) -> result {
431
443
// instance is required.
432
444
fn metrics ( bcx : @block_ctxt , t : ty:: t , opt_v : option < ValueRef > )
433
445
-> metrics_result {
434
- let ccx = bcx_ccx ( cx) ;
446
+ assert ( option:: is_some ( opt_v) ||
447
+ !ty:: type_has_opaque_size ( bcx_tcx ( bcx) , t) ) ;
448
+ let ccx = bcx_ccx ( bcx) ;
435
449
if check type_has_static_size ( ccx, t) {
436
- let sp = cx . sp ;
437
- let sz = llsize_of ( bcx_ccx ( cx ) , type_of ( ccx, sp, t) ) ;
438
- let align = llalign_of ( bcx_ccx ( cx ) , type_of ( ccx, sp, t) ) ;
450
+ let sp = bcx . sp ;
451
+ let sz = llsize_of ( bcx_ccx ( bcx ) , type_of ( ccx, sp, t) ) ;
452
+ let align = llalign_of ( bcx_ccx ( bcx ) , type_of ( ccx, sp, t) ) ;
439
453
ret { bcx : bcx, sz : sz, align : align} ;
440
454
} else {
441
455
ret dynamic_metrics ( bcx, t, opt_v) ;
@@ -552,11 +566,11 @@ type metrics_result = {
552
566
} ;
553
567
554
568
fn dynamic_metrics ( bcx : @block_ctxt ,
555
- elts : [ ty:: t ] ,
556
- opts_v : option < ValueRef > ) -> metrics_result {
557
- fn compute_elements_metrics ( bcx : @block_ctxt ,
558
- elts : [ ty:: t ] ,
559
- opt_v : option < ValueRef > ) -> metrics_result {
569
+ t : ty:: t ,
570
+ opt_v : option < ValueRef > ) -> metrics_result {
571
+ fn c_struct_metrics ( bcx : @block_ctxt ,
572
+ elts : [ ty:: t ] ,
573
+ opt_v : option < ValueRef > ) -> metrics_result {
560
574
//
561
575
// C padding rules:
562
576
//
@@ -570,40 +584,40 @@ fn dynamic_metrics(bcx: @block_ctxt,
570
584
let max_align = C_int ( bcx_ccx ( bcx) , 1 ) ;
571
585
for e: ty:: t in elts {
572
586
let opt_ev = option:: map ( opt_v) { |v| ptr_offs ( bcx, v, off) } ;
573
- let elt_align = align_of ( bcx, e, opt_ev) ;
574
- bcx = elt_align. bcx ;
575
- let elt_size = size_of ( bcx, e, opt_ev) ;
576
- bcx = elt_size. bcx ;
577
- let aligned_off = align_to ( bcx, off, elt_align. val ) ;
578
- off = Add ( bcx, aligned_off, elt_size. val ) ;
579
- max_align = umax ( bcx, max_align, elt_align. val ) ;
587
+ let elt_metrics = metrics ( bcx, e, opt_ev) ;
588
+ bcx = elt_metrics. bcx ;
589
+ let aligned_off = align_to ( bcx, off, elt_metrics. align ) ;
590
+ off = Add ( bcx, aligned_off, elt_metrics. sz ) ;
591
+ max_align = umax ( bcx, max_align, elt_metrics. align ) ;
580
592
}
593
+ off = align_to ( bcx, off, max_align) ;
581
594
ret { bcx : bcx, sz : off, align : max_align } ;
582
595
}
583
596
584
597
alt ty:: struct ( bcx_tcx ( bcx) , t) {
585
598
ty:: ty_param ( p, _) {
586
- let { bcx, value: szptr } =
587
- field_of_tydesc ( bcx, t, false , abi:: tydesc_field_size) ;
588
- let { bcx, value: aptr } =
589
- field_of_tydesc ( bcx, t, false , abi:: tydesc_field_align) ;
590
- ret { bcx : bcx, sz : Load ( szptr) , align : Load ( align) } ;
599
+ let ti = none :: < @tydesc_info > ;
600
+ let { bcx, val: tydesc } =
601
+ get_tydesc ( bcx, t, false , tps_normal, ti) . result ;
602
+ let sz = Load ( bcx, GEPi ( bcx, tydesc, [ 0 , abi:: tydesc_field_size] ) ) ;
603
+ let al = Load ( bcx, GEPi ( bcx, tydesc, [ 0 , abi:: tydesc_field_align] ) ) ;
604
+ ret { bcx : bcx, sz : sz, align : al } ;
591
605
}
592
606
ty:: ty_rec ( flds) {
593
607
let tys: [ ty:: t ] = [ ] ;
594
608
for f: ty:: field in flds { tys += [ f. mt . ty ] ; }
595
- ret compute_elements_metrics ( bcx, tys, opt_v) ;
609
+ ret c_struct_metrics ( bcx, tys, opt_v) ;
596
610
}
597
611
ty:: ty_tup ( elts) {
598
612
let tys = [ ] ;
599
613
for tp in elts { tys += [ tp] ; }
600
- ret compute_elements_metrics ( bcx, tys, opt_v) ;
614
+ ret c_struct_metrics ( bcx, tys, opt_v) ;
601
615
}
602
616
ty:: ty_tag ( tid, tps) {
603
617
let bcx = bcx;
604
618
let ccx = bcx_ccx ( bcx) ;
605
- // Compute max(variant sizes) and max(variant alignments).
606
619
620
+ // Compute max(variant sizes) and max(variant alignments).
607
621
let max_size: ValueRef = alloca ( bcx, ccx. int_type ) ;
608
622
Store ( bcx, C_int ( ccx, 0 ) , max_size) ;
609
623
let variants = ty:: tag_variants ( bcx_tcx ( bcx) , tid) ;
@@ -616,9 +630,16 @@ fn dynamic_metrics(bcx: @block_ctxt,
616
630
let t = ty:: substitute_type_params ( bcx_tcx ( bcx) , tps, raw_ty) ;
617
631
tys += [ t] ;
618
632
}
619
- let rslt = align_elements ( bcx, tys, opt_v) ;
633
+
634
+ // Note: we do not pass in opt_v here for the value but rather
635
+ // none. The reason is that what we would want to pass in is a
636
+ // ptr to the blob data of the tag, but this is impossible until
637
+ // we know the size/alignment of the blob data. Therefore, it is
638
+ // not legal to have a tag type that contains an interior opaque
639
+ // type. Fortunately this will never happen.
640
+ let rslt = c_struct_metrics ( bcx, tys, none) ;
620
641
bcx = rslt. bcx ;
621
- let this_size = rslt. val ;
642
+ let this_size = rslt. sz ;
622
643
let old_max_size = Load ( bcx, max_size) ;
623
644
Store ( bcx, umax ( bcx, this_size, old_max_size) , max_size) ;
624
645
}
@@ -651,7 +672,7 @@ fn dynamic_metrics(bcx: @block_ctxt,
651
672
let tdptr = Load ( bcx, tdptrptr) ;
652
673
let sz = Load ( bcx, GEPi ( bcx, tdptr, [ 0 , abi:: tydesc_field_size] ) ) ;
653
674
let align = Load ( bcx, GEPi ( bcx, tdptr, [ 0 , abi:: tydesc_field_align] ) ) ;
654
- ret { bcx : bcx, sz : sz, align : sz } ;
675
+ ret { bcx : bcx, sz : sz, align : align } ;
655
676
}
656
677
}
657
678
}
@@ -661,7 +682,7 @@ fn dynamic_metrics(bcx: @block_ctxt,
661
682
// return type, use bump_ptr().
662
683
fn ptr_offs ( bcx : @block_ctxt , base : ValueRef , sz : ValueRef ) -> ValueRef {
663
684
let raw = PointerCast ( bcx, base, T_ptr ( T_i8 ( ) ) ) ;
664
- GEP ( bcx, raw, [ sz] ) ;
685
+ GEP ( bcx, raw, [ sz] )
665
686
}
666
687
667
688
// Increment a pointer by a given amount and then cast it to be a pointer
@@ -760,7 +781,7 @@ fn GEP_tup_like(bcx: @block_ctxt, t: ty::t, base: ValueRef, ixs: [int])
760
781
let args = [ ] ;
761
782
for typ: ty:: t in s. prefix { args += [ typ] ; }
762
783
let prefix_ty = ty:: mk_tup ( bcx_tcx ( bcx) , args) ;
763
- let { bcx, val : prefix_sz } = size_of ( bcx, prefix_ty) ;
784
+ let { bcx, sz : prefix_sz , align : _ } = metrics ( bcx, prefix_ty, some ( base ) ) ;
764
785
let { bcx, val: align } = align_of ( bcx, s. target ) ;
765
786
let sz = align_to ( bcx, prefix_sz, align) ;
766
787
ret rslt( bcx, bump_ptr ( bcx, s. target , base, sz) ) ;
@@ -898,7 +919,6 @@ fn field_of_tydesc(cx: @block_ctxt, t: ty::t, escapes: bool, field: int) ->
898
919
GEPi ( tydesc. bcx , tydesc. val , [ 0 , field] ) ) ;
899
920
}
900
921
901
-
902
922
// Given a type containing ty params, build a vector containing a ValueRef for
903
923
// each of the ty params it uses (from the current frame) and a vector of the
904
924
// indices of the ty params present in the type. This is used solely for
@@ -2003,21 +2023,21 @@ fn call_bzero(cx: @block_ctxt, dst: ValueRef, n_bytes: ValueRef,
2003
2023
Call ( cx, memset, [ dst_ptr, C_u8 ( 0 u) , size, align, volatile] ) ) ;
2004
2024
}
2005
2025
2006
- fn memmove_ty ( cx : @block_ctxt , dst : ValueRef , src : ValueRef , t : ty:: t ) ->
2026
+ fn memmove_ty ( bcx : @block_ctxt , dst : ValueRef , src : ValueRef , t : ty:: t ) ->
2007
2027
@block_ctxt {
2008
- let ccx = bcx_ccx ( cx ) ;
2028
+ let ccx = bcx_ccx ( bcx ) ;
2009
2029
if check type_has_static_size ( ccx, t) {
2010
- if ty:: type_is_structural ( bcx_tcx ( cx ) , t) {
2011
- let sp = cx . sp ;
2030
+ if ty:: type_is_structural ( bcx_tcx ( bcx ) , t) {
2031
+ let sp = bcx . sp ;
2012
2032
let llsz = llsize_of ( ccx, type_of ( ccx, sp, t) ) ;
2013
- ret call_memmove ( cx , dst, src, llsz) . bcx ;
2033
+ ret call_memmove ( bcx , dst, src, llsz) . bcx ;
2014
2034
}
2015
- Store ( cx , Load ( cx , src) , dst) ;
2016
- ret cx ;
2035
+ Store ( bcx , Load ( bcx , src) , dst) ;
2036
+ ret bcx ;
2017
2037
}
2018
2038
2019
- let llsz = size_of ( cx , t) ;
2020
- ret call_memmove ( llsz . bcx , dst, src, llsz. val ) . bcx ;
2039
+ let { bcx , sz : llsz , align : _ } = metrics ( bcx , t, some ( src ) ) ;
2040
+ ret call_memmove ( bcx, dst, src, llsz) . bcx ;
2021
2041
}
2022
2042
2023
2043
tag copy_action { INIT ; DROP_EXISTING ; }
0 commit comments