@@ -1124,10 +1124,10 @@ pub fn compare_values(cx: block,
1124
1124
}
1125
1125
}
1126
1126
1127
- pub fn store_non_ref_bindings ( bcx : block ,
1128
- data : & ArmData ,
1129
- opt_temp_cleanups : Option < & mut ~[ ValueRef ] > )
1130
- -> block
1127
+ fn store_non_ref_bindings ( bcx : block ,
1128
+ bindings_map : & BindingsMap ,
1129
+ mut opt_temp_cleanups : Option < & mut ~[ ValueRef ] > )
1130
+ -> block
1131
1131
{
1132
1132
/*!
1133
1133
*
@@ -1139,8 +1139,7 @@ pub fn store_non_ref_bindings(bcx: block,
1139
1139
*/
1140
1140
1141
1141
let mut bcx = bcx;
1142
- let mut opt_temp_cleanups = opt_temp_cleanups;
1143
- for data. bindings_map. each_value |& binding_info| {
1142
+ for bindings_map. each_value |& binding_info| {
1144
1143
match binding_info. trmode {
1145
1144
TrByValue ( is_move, lldest) => {
1146
1145
let llval = Load ( bcx, binding_info. llmatch ) ; // get a T*
@@ -1166,16 +1165,22 @@ pub fn store_non_ref_bindings(bcx: block,
1166
1165
return bcx;
1167
1166
}
1168
1167
1169
- pub fn insert_lllocals ( bcx : block ,
1170
- data : & ArmData ,
1171
- add_cleans : bool ) -> block {
1168
+ fn insert_lllocals ( bcx : block ,
1169
+ bindings_map : & BindingsMap ,
1170
+ binding_mode : IrrefutablePatternBindingMode ,
1171
+ add_cleans : bool ) -> block {
1172
1172
/*!
1173
- *
1174
1173
* For each binding in `data.bindings_map`, adds an appropriate entry into
1175
1174
* the `fcx.lllocals` map. If add_cleans is true, then adds cleanups for
1176
- * the bindings. */
1175
+ * the bindings.
1176
+ */
1177
1177
1178
- for data. bindings_map. each_value |& binding_info| {
1178
+ let llmap = match binding_mode {
1179
+ BindLocal => bcx. fcx . lllocals ,
1180
+ BindArgument => bcx. fcx . llargs
1181
+ } ;
1182
+
1183
+ for bindings_map. each_value |& binding_info| {
1179
1184
let llval = match binding_info. trmode {
1180
1185
// By value bindings: use the stack slot that we
1181
1186
// copied/moved the value into
@@ -1193,8 +1198,10 @@ pub fn insert_lllocals(bcx: block,
1193
1198
}
1194
1199
} ;
1195
1200
1196
- bcx. fcx . lllocals . insert ( binding_info. id ,
1197
- local_mem ( llval) ) ;
1201
+ debug ! ( "binding %? to %s" ,
1202
+ binding_info. id,
1203
+ val_str( bcx. ccx( ) . tn, llval) ) ;
1204
+ llmap. insert ( binding_info. id , local_mem ( llval) ) ;
1198
1205
}
1199
1206
return bcx;
1200
1207
}
@@ -1215,8 +1222,8 @@ pub fn compile_guard(bcx: block,
1215
1222
1216
1223
let mut bcx = bcx;
1217
1224
let mut temp_cleanups = ~[ ] ;
1218
- bcx = store_non_ref_bindings ( bcx, data, Some ( & mut temp_cleanups) ) ;
1219
- bcx = insert_lllocals ( bcx, data, false ) ;
1225
+ bcx = store_non_ref_bindings ( bcx, & data. bindings_map , Some ( & mut temp_cleanups) ) ;
1226
+ bcx = insert_lllocals ( bcx, & data. bindings_map , BindLocal , false ) ;
1220
1227
1221
1228
let val = unpack_result ! ( bcx, {
1222
1229
do with_scope_result( bcx, guard_expr. info( ) ,
@@ -1613,6 +1620,42 @@ pub fn trans_match(bcx: block,
1613
1620
}
1614
1621
}
1615
1622
1623
+ fn create_bindings_map( bcx : block , pat : @ast:: pat ) -> BindingsMap {
1624
+ // Create the bindings map, which is a mapping from each binding name
1625
+ // to an alloca() that will be the value for that local variable.
1626
+ // Note that we use the names because each binding will have many ids
1627
+ // from the various alternatives.
1628
+ let ccx = bcx. ccx ( ) ;
1629
+ let tcx = bcx. tcx ( ) ;
1630
+ let mut bindings_map = HashMap :: new ( ) ;
1631
+ do pat_bindings ( tcx. def_map , pat) |bm, p_id, _s, path| {
1632
+ let ident = path_to_ident ( path) ;
1633
+ let variable_ty = node_id_type ( bcx, p_id) ;
1634
+ let llvariable_ty = type_of:: type_of ( ccx, variable_ty) ;
1635
+
1636
+ let llmatch, trmode;
1637
+ match bm {
1638
+ ast:: bind_by_copy | ast:: bind_infer => {
1639
+ // in this case, the final type of the variable will be T,
1640
+ // but during matching we need to store a *T as explained
1641
+ // above
1642
+ let is_move = ccx. maps . moves_map . contains ( & p_id) ;
1643
+ llmatch = alloca ( bcx, T_ptr ( llvariable_ty) ) ;
1644
+ trmode = TrByValue ( is_move, alloca ( bcx, llvariable_ty) ) ;
1645
+ }
1646
+ ast:: bind_by_ref( _) => {
1647
+ llmatch = alloca ( bcx, llvariable_ty) ;
1648
+ trmode = TrByRef ;
1649
+ }
1650
+ } ;
1651
+ bindings_map. insert ( ident, BindingInfo {
1652
+ llmatch : llmatch, trmode : trmode,
1653
+ id : p_id, ty : variable_ty
1654
+ } ) ;
1655
+ }
1656
+ return bindings_map;
1657
+ }
1658
+
1616
1659
pub fn trans_match_inner ( scope_cx : block ,
1617
1660
discr_expr : @ast:: expr ,
1618
1661
arms : & [ ast:: arm ] ,
@@ -1629,41 +1672,9 @@ pub fn trans_match_inner(scope_cx: block,
1629
1672
}
1630
1673
1631
1674
let mut arm_datas = ~[ ] , matches = ~[ ] ;
1632
- for arms. each |arm| {
1633
- let body = scope_block ( bcx, arm. body . info ( ) , "case_body" ) ;
1634
-
1635
- // Create the bindings map, which is a mapping from each binding name
1636
- // to an alloca() that will be the value for that local variable.
1637
- // Note that we use the names because each binding will have many ids
1638
- // from the various alternatives.
1639
- let mut bindings_map = HashMap :: new ( ) ;
1640
- do pat_bindings ( tcx. def_map , arm. pats [ 0 ] ) |bm, p_id, _s, path| {
1641
- let ident = path_to_ident ( path) ;
1642
- let variable_ty = node_id_type ( bcx, p_id) ;
1643
- let llvariable_ty = type_of:: type_of ( bcx. ccx ( ) , variable_ty) ;
1644
-
1645
- let llmatch, trmode;
1646
- match bm {
1647
- ast:: bind_by_copy | ast:: bind_infer => {
1648
- // in this case, the final type of the variable will be T,
1649
- // but during matching we need to store a *T as explained
1650
- // above
1651
- let is_move =
1652
- scope_cx. ccx ( ) . maps . moves_map . contains ( & p_id) ;
1653
- llmatch = alloca ( bcx, T_ptr ( llvariable_ty) ) ;
1654
- trmode = TrByValue ( is_move, alloca ( bcx, llvariable_ty) ) ;
1655
- }
1656
- ast:: bind_by_ref( _) => {
1657
- llmatch = alloca ( bcx, llvariable_ty) ;
1658
- trmode = TrByRef ;
1659
- }
1660
- } ;
1661
- bindings_map. insert ( ident, BindingInfo {
1662
- llmatch : llmatch, trmode : trmode,
1663
- id : p_id, ty : variable_ty
1664
- } ) ;
1665
- }
1666
-
1675
+ for vec:: each( arms) |arm| {
1676
+ let body = scope_block ( bcx, arm. body . info ( ) , ~"case_body") ;
1677
+ let bindings_map = create_bindings_map ( bcx, arm. pats [ 0 ] ) ;
1667
1678
let arm_data = @ArmData { bodycx : body,
1668
1679
arm : arm,
1669
1680
bindings_map : bindings_map} ;
@@ -1697,11 +1708,11 @@ pub fn trans_match_inner(scope_cx: block,
1697
1708
// is just to reduce code space. See extensive comment at the start
1698
1709
// of the file for more details.
1699
1710
if arm_data. arm . guard . is_none ( ) {
1700
- bcx = store_non_ref_bindings ( bcx, * arm_data, None ) ;
1711
+ bcx = store_non_ref_bindings ( bcx, & arm_data. bindings_map , None ) ;
1701
1712
}
1702
1713
1703
1714
// insert bindings into the lllocals map and add cleanups
1704
- bcx = insert_lllocals ( bcx, * arm_data, true ) ;
1715
+ bcx = insert_lllocals ( bcx, & arm_data. bindings_map , BindLocal , true ) ;
1705
1716
1706
1717
bcx = controlflow:: trans_block ( bcx, & arm_data. arm . body , dest) ;
1707
1718
bcx = trans_block_cleanups ( bcx, block_cleanups ( arm_data. bodycx ) ) ;
0 commit comments