@@ -17,7 +17,7 @@ use adt;
17
17
use base;
18
18
use build;
19
19
use callee:: { Callee , CalleeData , Fn , Intrinsic , NamedTupleConstructor , Virtual } ;
20
- use common:: { self , type_is_fat_ptr , Block , BlockAndBuilder , LandingPad } ;
20
+ use common:: { self , Block , BlockAndBuilder , LandingPad } ;
21
21
use common:: { C_bool , C_str_slice , C_struct , C_u32 , C_undef } ;
22
22
use consts;
23
23
use debuginfo:: DebugLoc ;
@@ -36,7 +36,7 @@ use super::analyze::CleanupKind;
36
36
use super :: constant:: Const ;
37
37
use super :: lvalue:: { LvalueRef , load_fat_ptr} ;
38
38
use super :: operand:: OperandRef ;
39
- use super :: operand:: OperandValue :: { self , FatPtr , Immediate , Ref } ;
39
+ use super :: operand:: OperandValue :: * ;
40
40
41
41
impl < ' bcx , ' tcx > MirContext < ' bcx , ' tcx > {
42
42
pub fn trans_block ( & mut self , bb : mir:: BasicBlock ) {
@@ -410,8 +410,8 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
410
410
}
411
411
}
412
412
413
- let val = self . trans_operand ( & bcx, arg) . val ;
414
- self . trans_argument ( & bcx, val , & mut llargs, & fn_ty,
413
+ let op = self . trans_operand ( & bcx, arg) ;
414
+ self . trans_argument ( & bcx, op , & mut llargs, & fn_ty,
415
415
& mut idx, & mut callee. data ) ;
416
416
}
417
417
if let Some ( tup) = untuple {
@@ -449,7 +449,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
449
449
if let ReturnDest :: IndirectOperand ( dst, _) = ret_dest {
450
450
// Make a fake operand for store_return
451
451
let op = OperandRef {
452
- val : OperandValue :: Ref ( dst) ,
452
+ val : Ref ( dst) ,
453
453
ty : sig. output . unwrap ( )
454
454
} ;
455
455
self . store_return ( & bcx, ret_dest, fn_ty. ret , op) ;
@@ -487,7 +487,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
487
487
ret_bcx. at_start ( |ret_bcx| {
488
488
debug_loc. apply_to_bcx ( ret_bcx) ;
489
489
let op = OperandRef {
490
- val : OperandValue :: Immediate ( invokeret) ,
490
+ val : Immediate ( invokeret) ,
491
491
ty : sig. output . unwrap ( )
492
492
} ;
493
493
self . store_return ( & ret_bcx, ret_dest, fn_ty. ret , op) ;
@@ -498,7 +498,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
498
498
fn_ty. apply_attrs_callsite ( llret) ;
499
499
if let Some ( ( _, target) ) = * destination {
500
500
let op = OperandRef {
501
- val : OperandValue :: Immediate ( llret) ,
501
+ val : Immediate ( llret) ,
502
502
ty : sig. output . unwrap ( )
503
503
} ;
504
504
self . store_return ( & bcx, ret_dest, fn_ty. ret , op) ;
@@ -513,25 +513,36 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
513
513
514
514
fn trans_argument ( & mut self ,
515
515
bcx : & BlockAndBuilder < ' bcx , ' tcx > ,
516
- val : OperandValue ,
516
+ mut op : OperandRef < ' tcx > ,
517
517
llargs : & mut Vec < ValueRef > ,
518
518
fn_ty : & FnType ,
519
519
next_idx : & mut usize ,
520
520
callee : & mut CalleeData ) {
521
- // Treat the values in a fat pointer separately.
522
- if let FatPtr ( ptr, meta) = val {
523
- if * next_idx == 0 {
524
- if let Virtual ( idx) = * callee {
525
- let llfn = bcx. with_block ( |bcx| {
526
- meth:: get_virtual_method ( bcx, meta, idx)
527
- } ) ;
528
- let llty = fn_ty. llvm_type ( bcx. ccx ( ) ) . ptr_to ( ) ;
529
- * callee = Fn ( bcx. pointercast ( llfn, llty) ) ;
521
+ if let Pair ( a, b) = op. val {
522
+ // Treat the values in a fat pointer separately.
523
+ if common:: type_is_fat_ptr ( bcx. tcx ( ) , op. ty ) {
524
+ let ( ptr, meta) = ( a, b) ;
525
+ if * next_idx == 0 {
526
+ if let Virtual ( idx) = * callee {
527
+ let llfn = bcx. with_block ( |bcx| {
528
+ meth:: get_virtual_method ( bcx, meta, idx)
529
+ } ) ;
530
+ let llty = fn_ty. llvm_type ( bcx. ccx ( ) ) . ptr_to ( ) ;
531
+ * callee = Fn ( bcx. pointercast ( llfn, llty) ) ;
532
+ }
530
533
}
534
+
535
+ let imm_op = |x| OperandRef {
536
+ val : Immediate ( x) ,
537
+ // We won't be checking the type again.
538
+ ty : bcx. tcx ( ) . types . err
539
+ } ;
540
+ self . trans_argument ( bcx, imm_op ( ptr) , llargs, fn_ty, next_idx, callee) ;
541
+ self . trans_argument ( bcx, imm_op ( meta) , llargs, fn_ty, next_idx, callee) ;
542
+ return ;
531
543
}
532
- self . trans_argument ( bcx, Immediate ( ptr) , llargs, fn_ty, next_idx, callee) ;
533
- self . trans_argument ( bcx, Immediate ( meta) , llargs, fn_ty, next_idx, callee) ;
534
- return ;
544
+
545
+ op = op. pack_if_pair ( bcx) ;
535
546
}
536
547
537
548
let arg = & fn_ty. args [ * next_idx] ;
@@ -547,15 +558,15 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
547
558
}
548
559
549
560
// Force by-ref if we have to load through a cast pointer.
550
- let ( mut llval, by_ref) = match val {
561
+ let ( mut llval, by_ref) = match op . val {
551
562
Immediate ( llval) if arg. is_indirect ( ) || arg. cast . is_some ( ) => {
552
563
let llscratch = build:: AllocaFcx ( bcx. fcx ( ) , arg. original_ty , "arg" ) ;
553
564
bcx. store ( llval, llscratch) ;
554
565
( llscratch, true )
555
566
}
556
567
Immediate ( llval) => ( llval, false ) ,
557
568
Ref ( llval) => ( llval, true ) ,
558
- FatPtr ( _ , _ ) => bug ! ( "fat pointers handled above" )
569
+ Pair ( .. ) => bug ! ( "pairs handled above" )
559
570
} ;
560
571
561
572
if by_ref && !arg. is_indirect ( ) {
@@ -602,12 +613,16 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
602
613
let ptr = adt:: trans_field_ptr_builder ( bcx, & base_repr, base, Disr ( 0 ) , n) ;
603
614
let val = if common:: type_is_fat_ptr ( bcx. tcx ( ) , ty) {
604
615
let ( lldata, llextra) = load_fat_ptr ( bcx, ptr) ;
605
- FatPtr ( lldata, llextra)
616
+ Pair ( lldata, llextra)
606
617
} else {
607
618
// trans_argument will load this if it needs to
608
619
Ref ( ptr)
609
620
} ;
610
- self . trans_argument ( bcx, val, llargs, fn_ty, next_idx, callee) ;
621
+ let op = OperandRef {
622
+ val : val,
623
+ ty : ty
624
+ } ;
625
+ self . trans_argument ( bcx, op, llargs, fn_ty, next_idx, callee) ;
611
626
}
612
627
613
628
}
@@ -619,11 +634,29 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
619
634
elem = bcx. trunc ( elem, Type :: i1 ( bcx. ccx ( ) ) ) ;
620
635
}
621
636
// If the tuple is immediate, the elements are as well
622
- let val = Immediate ( elem) ;
623
- self . trans_argument ( bcx, val, llargs, fn_ty, next_idx, callee) ;
637
+ let op = OperandRef {
638
+ val : Immediate ( elem) ,
639
+ ty : ty
640
+ } ;
641
+ self . trans_argument ( bcx, op, llargs, fn_ty, next_idx, callee) ;
642
+ }
643
+ }
644
+ Pair ( a, b) => {
645
+ let elems = [ a, b] ;
646
+ for ( n, & ty) in arg_types. iter ( ) . enumerate ( ) {
647
+ let mut elem = elems[ n] ;
648
+ // Truncate bools to i1, if needed
649
+ if ty. is_bool ( ) && common:: val_ty ( elem) != Type :: i1 ( bcx. ccx ( ) ) {
650
+ elem = bcx. trunc ( elem, Type :: i1 ( bcx. ccx ( ) ) ) ;
651
+ }
652
+ // Pair is always made up of immediates
653
+ let op = OperandRef {
654
+ val : Immediate ( elem) ,
655
+ ty : ty
656
+ } ;
657
+ self . trans_argument ( bcx, op, llargs, fn_ty, next_idx, callee) ;
624
658
}
625
659
}
626
- FatPtr ( _, _) => bug ! ( "tuple is a fat pointer?!" )
627
660
}
628
661
629
662
}
@@ -779,7 +812,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
779
812
let f = Callee :: def ( bcx. ccx ( ) , def_id, substs) ;
780
813
let datum = f. reify ( bcx. ccx ( ) ) ;
781
814
val = OperandRef {
782
- val : OperandValue :: Immediate ( datum. val ) ,
815
+ val : Immediate ( datum. val ) ,
783
816
ty : datum. ty
784
817
} ;
785
818
}
@@ -806,17 +839,15 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
806
839
self . temps [ idx as usize ] = TempRef :: Operand ( Some ( op) ) ;
807
840
}
808
841
DirectOperand ( idx) => {
809
- let op = if type_is_fat_ptr ( bcx. tcx ( ) , op. ty ) {
810
- let llval = op. immediate ( ) ;
811
- let ptr = bcx. extract_value ( llval, 0 ) ;
812
- let meta = bcx. extract_value ( llval, 1 ) ;
813
-
814
- OperandRef {
815
- val : OperandValue :: FatPtr ( ptr, meta) ,
816
- ty : op. ty
817
- }
842
+ // If there is a cast, we have to store and reload.
843
+ let op = if ret_ty. cast . is_some ( ) {
844
+ let tmp = bcx. with_block ( |bcx| {
845
+ base:: alloc_ty ( bcx, op. ty , "tmp_ret" )
846
+ } ) ;
847
+ ret_ty. store ( bcx, op. immediate ( ) , tmp) ;
848
+ self . trans_load ( bcx, tmp, op. ty )
818
849
} else {
819
- op
850
+ op. unpack_if_pair ( bcx )
820
851
} ;
821
852
self . temps [ idx as usize ] = TempRef :: Operand ( Some ( op) ) ;
822
853
}
0 commit comments