@@ -679,9 +679,10 @@ fn copy_ty(@block_ctxt cx,
679
679
if ( ! is_init) {
680
680
r = drop_ty ( r. bcx , dst, t) ;
681
681
}
682
- auto llty = type_of ( cx. fcx . ccx , t) ;
683
- r = build_memcpy ( r. bcx , dst, src, llty) ;
684
- ret res( r. bcx , src) ;
682
+ // In this one surprising case, we do a load/store on
683
+ // structure types. This results in a memcpy. Usually
684
+ // we talk about structures by pointers in this file.
685
+ ret res( r. bcx , r. bcx . build . Store ( r. bcx . build . Load ( src) , dst) ) ;
685
686
}
686
687
687
688
cx. fcx . ccx . sess . bug ( "unexpected type in trans.copy_ty: " +
@@ -778,7 +779,7 @@ fn node_type(@crate_ctxt cx, &ast.ann a) -> TypeRef {
778
779
}
779
780
780
781
impure fn trans_unary ( @block_ctxt cx , ast. unop op ,
781
- & ast . expr e, & ast . ann a) -> result {
782
+ @ ast. expr e , & ast . ann a) -> result {
782
783
783
784
auto sub = trans_expr ( cx, e) ;
784
785
@@ -811,7 +812,7 @@ impure fn trans_unary(@block_ctxt cx, ast.unop op,
811
812
}
812
813
813
814
impure fn trans_binary ( @block_ctxt cx , ast. binop op ,
814
- & ast . expr a, & ast . expr b) -> result {
815
+ @ ast. expr a , @ ast. expr b ) -> result {
815
816
816
817
// First couple cases are lazy:
817
818
@@ -997,7 +998,7 @@ fn join_results(@block_ctxt parent_cx,
997
998
ret res( join_cx, phi) ;
998
999
}
999
1000
1000
- impure fn trans_if ( @block_ctxt cx , & ast. expr cond ,
1001
+ impure fn trans_if ( @block_ctxt cx , @ ast. expr cond ,
1001
1002
& ast. block thn , & option. t[ ast. block] els ) -> result {
1002
1003
1003
1004
auto cond_res = trans_expr ( cx, cond) ;
@@ -1023,7 +1024,7 @@ impure fn trans_if(@block_ctxt cx, &ast.expr cond,
1023
1024
vec ( then_res, else_res) ) ;
1024
1025
}
1025
1026
1026
- impure fn trans_while ( @block_ctxt cx , & ast. expr cond ,
1027
+ impure fn trans_while ( @block_ctxt cx , @ ast. expr cond ,
1027
1028
& ast. block body ) -> result {
1028
1029
1029
1030
auto cond_cx = new_sub_block_ctxt ( cx, "while cond" ) ;
@@ -1043,7 +1044,7 @@ impure fn trans_while(@block_ctxt cx, &ast.expr cond,
1043
1044
}
1044
1045
1045
1046
impure fn trans_do_while ( @block_ctxt cx , & ast. block body ,
1046
- & ast. expr cond ) -> result {
1047
+ @ ast. expr cond ) -> result {
1047
1048
1048
1049
auto body_cx = new_sub_block_ctxt ( cx, "do-while loop body" ) ;
1049
1050
auto next_cx = new_sub_block_ctxt ( cx, "next" ) ;
@@ -1058,42 +1059,66 @@ impure fn trans_do_while(@block_ctxt cx, &ast.block body,
1058
1059
ret res( next_cx, body_res. val ) ;
1059
1060
}
1060
1061
1061
- // The additional bool returned indicates whether it's a local
1062
- // (that is represented as an alloca, hence needs a 'load' to be
1063
- // used as an rval ).
1062
+ // The additional bool returned indicates whether it's mem (that is
1063
+ // represented as an alloca or heap , hence needs a 'load' to be used as an
1064
+ // immediate ).
1064
1065
1065
- fn trans_lval ( @block_ctxt cx , & ast . expr e)
1066
- -> tup ( result , bool , ast. def_id ) {
1067
- alt ( e. node ) {
1068
- case ( ast. expr_name ( ?n, ?dopt, _) ) {
1069
- alt ( dopt) {
1070
- case ( some[ ast. def ] ( ?def) ) {
1071
- alt ( def) {
1072
- case ( ast. def_arg ( ?did) ) {
1073
- check ( cx. fcx . llargs . contains_key ( did) ) ;
1074
- ret tup( res ( cx, cx. fcx . llargs . get ( did) ) ,
1075
- false , did) ;
1076
- }
1077
- case ( ast. def_local ( ?did) ) {
1078
- check ( cx. fcx . lllocals . contains_key ( did) ) ;
1079
- ret tup( res ( cx, cx. fcx . lllocals . get ( did) ) ,
1080
- true , did) ;
1081
- }
1082
- case ( ast. def_fn ( ?did) ) {
1083
- check ( cx. fcx . ccx . fn_ids . contains_key ( did) ) ;
1084
- ret tup( res ( cx, cx. fcx . ccx . fn_ids . get ( did) ) ,
1085
- false , did) ;
1086
- }
1087
- case ( _) {
1088
- cx. fcx . ccx . sess . unimpl ( "def variant in trans" ) ;
1089
- }
1090
- }
1066
+ fn trans_name ( @block_ctxt cx , & ast. name n , & option. t[ ast. def] dopt )
1067
+ -> tup ( result , bool ) {
1068
+ alt ( dopt) {
1069
+ case ( some[ ast. def ] ( ?def) ) {
1070
+ alt ( def) {
1071
+ case ( ast. def_arg ( ?did) ) {
1072
+ check ( cx. fcx . llargs . contains_key ( did) ) ;
1073
+ ret tup( res ( cx, cx. fcx . llargs . get ( did) ) ,
1074
+ false ) ;
1075
+ }
1076
+ case ( ast. def_local ( ?did) ) {
1077
+ check ( cx. fcx . lllocals . contains_key ( did) ) ;
1078
+ ret tup( res ( cx, cx. fcx . lllocals . get ( did) ) ,
1079
+ true ) ;
1091
1080
}
1092
- case ( none[ ast. def ] ) {
1093
- cx. fcx . ccx . sess . err ( "unresolved expr_name in trans" ) ;
1081
+ case ( ast. def_fn ( ?did) ) {
1082
+ check ( cx. fcx . ccx . fn_ids . contains_key ( did) ) ;
1083
+ ret tup( res ( cx, cx. fcx . ccx . fn_ids . get ( did) ) ,
1084
+ false ) ;
1085
+ }
1086
+ case ( _) {
1087
+ cx. fcx . ccx . sess . unimpl ( "def variant in trans" ) ;
1094
1088
}
1095
1089
}
1096
1090
}
1091
+ case ( none[ ast. def ] ) {
1092
+ cx. fcx . ccx . sess . err ( "unresolved expr_name in trans" ) ;
1093
+ }
1094
+ }
1095
+ fail;
1096
+ }
1097
+
1098
+ fn trans_field ( @block_ctxt cx , & ast. span sp , @ast. expr base ,
1099
+ & ast. ident field , & ast. ann ann ) -> tup ( result , bool ) {
1100
+ auto lv = trans_lval ( cx, base) ;
1101
+ auto r = lv. _0 ;
1102
+ auto ty = typeck. expr_ty ( base) ;
1103
+ alt ( ty. struct ) {
1104
+ case ( typeck. ty_tup ( ?fields) ) {
1105
+ let uint ix = typeck. field_num ( cx. fcx . ccx . sess , sp, field) ;
1106
+ auto v = r. bcx . build . GEP ( r. val , vec ( C_int ( 0 ) , C_int ( ix as int ) ) ) ;
1107
+ ret tup( res ( r. bcx , v) , lv. _1 ) ;
1108
+ }
1109
+ }
1110
+ cx. fcx . ccx . sess . unimpl ( "field variant in trans_field" ) ;
1111
+ fail;
1112
+ }
1113
+
1114
+ fn trans_lval ( @block_ctxt cx , @ast. expr e ) -> tup ( result , bool ) {
1115
+ alt ( e. node ) {
1116
+ case ( ast. expr_name ( ?n, ?dopt, _) ) {
1117
+ ret trans_name ( cx, n, dopt) ;
1118
+ }
1119
+ case ( ast. expr_field ( ?base, ?ident, ?ann) ) {
1120
+ ret trans_field ( cx, e. span , base, ident, ann) ;
1121
+ }
1097
1122
}
1098
1123
cx. fcx . ccx . sess . unimpl ( "expr variant in trans_lval" ) ;
1099
1124
fail;
@@ -1105,15 +1130,15 @@ impure fn trans_exprs(@block_ctxt cx, &vec[@ast.expr] es)
1105
1130
let @block_ctxt bcx = cx;
1106
1131
1107
1132
for ( @ast. expr e in es ) {
1108
- auto res = trans_expr ( bcx, * e) ;
1133
+ auto res = trans_expr ( bcx, e) ;
1109
1134
vs += res. val ;
1110
1135
bcx = res. bcx ;
1111
1136
}
1112
1137
1113
1138
ret tup( bcx, vs) ;
1114
1139
}
1115
1140
1116
- impure fn trans_cast ( @block_ctxt cx, & ast. expr e, & ast. ann ann) -> result {
1141
+ impure fn trans_cast ( @block_ctxt cx, @ ast. expr e, & ast. ann ann) -> result {
1117
1142
auto e_res = trans_expr ( cx, e) ;
1118
1143
auto llsrctype = val_ty ( e_res. val ) ;
1119
1144
auto t = node_ann_type ( cx. fcx . ccx , ann) ;
@@ -1144,7 +1169,7 @@ impure fn trans_cast(@block_ctxt cx, &ast.expr e, &ast.ann ann) -> result {
1144
1169
ret e_res;
1145
1170
}
1146
1171
1147
- impure fn trans_call ( @block_ctxt cx, & ast. expr f,
1172
+ impure fn trans_call ( @block_ctxt cx, @ ast. expr f,
1148
1173
vec[ @ast. expr ] args) -> result {
1149
1174
auto f_res = trans_lval ( cx, f) ;
1150
1175
check ( ! f_res. _1 ) ;
@@ -1163,7 +1188,7 @@ impure fn trans_tup(@block_ctxt cx, vec[tup(bool, @ast.expr)] args,
1163
1188
auto r = res ( cx, C_nil ( ) ) ;
1164
1189
for ( tup( bool, @ast. expr) arg in args) {
1165
1190
auto t = typeck. expr_ty( arg. _1) ;
1166
- auto src_res = trans_expr( r. bcx, * arg. _1) ;
1191
+ auto src_res = trans_expr( r. bcx, arg. _1) ;
1167
1192
auto dst_elt = r. bcx. build. GEP ( tup_val, vec( C_int ( 0 ) , C_int ( i) ) ) ;
1168
1193
// FIXME: calculate copy init-ness in typestate.
1169
1194
r = copy_ty( src_res. bcx, true , dst_elt, src_res. val, t) ;
@@ -1173,46 +1198,31 @@ impure fn trans_tup(@block_ctxt cx, vec[tup(bool, @ast.expr)] args,
1173
1198
}
1174
1199
1175
1200
1176
- impure fn trans_field( @block_ctxt cx, & ast. span sp, @ast. expr base,
1177
- & ast. ident field, & ast. ann ann) -> result {
1178
- auto r = trans_expr( cx, * base) ;
1179
- auto ty = typeck. expr_ty( base) ;
1180
- alt ( ty. struct ) {
1181
- case ( typeck. ty_tup( ?fields) ) {
1182
- let uint ix = typeck. field_num( cx. fcx. ccx. sess, sp, field) ;
1183
- auto v = r. bcx. build. GEP ( r. val, vec( C_int ( ix as int) ) ) ;
1184
- ret res( r. bcx, v) ;
1185
- }
1186
- }
1187
- cx. fcx. ccx. sess. unimpl( "field variant in trans_field" ) ;
1188
- fail;
1189
- }
1190
-
1191
1201
1192
- impure fn trans_expr( @block_ctxt cx, & ast. expr e) -> result {
1202
+ impure fn trans_expr( @block_ctxt cx, @ ast. expr e) -> result {
1193
1203
alt ( e. node) {
1194
1204
case ( ast. expr_lit( ?lit, _) ) {
1195
1205
ret trans_lit( cx, * lit) ;
1196
1206
}
1197
1207
1198
1208
case ( ast. expr_unary( ?op, ?x, ?ann) ) {
1199
- ret trans_unary( cx, op, * x, ann) ;
1209
+ ret trans_unary( cx, op, x, ann) ;
1200
1210
}
1201
1211
1202
1212
case ( ast. expr_binary( ?op, ?x, ?y, _) ) {
1203
- ret trans_binary( cx, op, * x, * y) ;
1213
+ ret trans_binary( cx, op, x, y) ;
1204
1214
}
1205
1215
1206
1216
case ( ast. expr_if( ?cond, ?thn, ?els, _) ) {
1207
- ret trans_if( cx, * cond, thn, els) ;
1217
+ ret trans_if( cx, cond, thn, els) ;
1208
1218
}
1209
1219
1210
1220
case ( ast. expr_while( ?cond, ?body, _) ) {
1211
- ret trans_while( cx, * cond, body) ;
1221
+ ret trans_while( cx, cond, body) ;
1212
1222
}
1213
1223
1214
1224
case ( ast. expr_do_while( ?body, ?cond, _) ) {
1215
- ret trans_do_while( cx, body, * cond) ;
1225
+ ret trans_do_while( cx, body, cond) ;
1216
1226
}
1217
1227
1218
1228
case ( ast. expr_block( ?blk, _) ) {
@@ -1226,46 +1236,45 @@ impure fn trans_expr(@block_ctxt cx, &ast.expr e) -> result {
1226
1236
ret res( next_cx, sub. val) ;
1227
1237
}
1228
1238
1229
- case ( ast. expr_name( _, _, _) ) {
1230
- auto sub = trans_lval( cx, e) ;
1231
- if ( sub. _1) {
1232
- ret res( sub. _0. bcx, cx. build. Load ( sub. _0. val) ) ;
1233
- } else {
1234
- ret sub. _0;
1235
- }
1236
- }
1237
-
1238
1239
case ( ast. expr_assign( ?dst, ?src, ?ann) ) {
1239
- auto lhs_res = trans_lval( cx, * dst) ;
1240
+ auto lhs_res = trans_lval( cx, dst) ;
1240
1241
check ( lhs_res. _1) ;
1241
- auto rhs_res = trans_expr( lhs_res. _0. bcx, * src) ;
1242
+ auto rhs_res = trans_expr( lhs_res. _0. bcx, src) ;
1242
1243
auto t = node_ann_type( cx. fcx. ccx, ann) ;
1243
1244
// FIXME: calculate copy init-ness in typestate.
1244
1245
ret copy_ty( rhs_res. bcx, true , lhs_res. _0. val, rhs_res. val, t) ;
1245
1246
}
1246
1247
1247
1248
case ( ast. expr_call( ?f, ?args, _) ) {
1248
- ret trans_call( cx, * f, args) ;
1249
+ ret trans_call( cx, f, args) ;
1249
1250
}
1250
1251
1251
1252
case ( ast. expr_cast( ?e, _, ?ann) ) {
1252
- ret trans_cast( cx, * e, ann) ;
1253
+ ret trans_cast( cx, e, ann) ;
1253
1254
}
1254
1255
1255
1256
case ( ast. expr_tup( ?args, ?ann) ) {
1256
1257
ret trans_tup( cx, args, ann) ;
1257
1258
}
1258
1259
1259
- case ( ast. expr_field( ?base, ?ident, ?ann) ) {
1260
- ret trans_field( cx, e. span, base, ident, ann) ;
1261
- }
1260
+ // lval cases fall through to trans_lval and then
1261
+ // possibly load the result (if it's non-structural).
1262
1262
1263
+ case ( _) {
1264
+ auto t = typeck. expr_ty( e) ;
1265
+ auto sub = trans_lval( cx, e) ;
1266
+ if ( sub . _1 && ! typeck. type_is_structural( t) ) {
1267
+ ret res( sub. _0. bcx, cx. build. Load ( sub. _0. val) ) ;
1268
+ } else {
1269
+ ret sub. _0;
1270
+ }
1271
+ }
1263
1272
}
1264
1273
cx. fcx. ccx. sess. unimpl( "expr variant in trans_expr" ) ;
1265
1274
fail;
1266
1275
}
1267
1276
1268
- impure fn trans_log( @block_ctxt cx, & ast. expr e) -> result {
1277
+ impure fn trans_log( @block_ctxt cx, @ ast. expr e) -> result {
1269
1278
alt ( e. node) {
1270
1279
case ( ast. expr_lit( ?lit, _) ) {
1271
1280
alt ( lit. node) {
@@ -1293,7 +1302,7 @@ impure fn trans_log(@block_ctxt cx, &ast.expr e) -> result {
1293
1302
}
1294
1303
}
1295
1304
1296
- impure fn trans_check_expr( @block_ctxt cx, & ast. expr e) -> result {
1305
+ impure fn trans_check_expr( @block_ctxt cx, @ ast. expr e) -> result {
1297
1306
auto cond_res = trans_expr( cx, e) ;
1298
1307
1299
1308
// FIXME: need pretty-printer.
@@ -1317,7 +1326,7 @@ impure fn trans_ret(@block_ctxt cx, &option.t[@ast.expr] e) -> result {
1317
1326
auto r = res( cx, C_nil ( ) ) ;
1318
1327
alt ( e) {
1319
1328
case ( some[ @ast. expr] ( ?x) ) {
1320
- r = trans_expr( cx, * x) ;
1329
+ r = trans_expr( cx, x) ;
1321
1330
}
1322
1331
}
1323
1332
@@ -1353,19 +1362,19 @@ impure fn trans_stmt(@block_ctxt cx, &ast.stmt s) -> result {
1353
1362
auto sub = res( cx, C_nil ( ) ) ;
1354
1363
alt ( s. node) {
1355
1364
case ( ast. stmt_log( ?a) ) {
1356
- sub. bcx = trans_log( cx, * a) . bcx;
1365
+ sub. bcx = trans_log( cx, a) . bcx;
1357
1366
}
1358
1367
1359
1368
case ( ast. stmt_check_expr( ?a) ) {
1360
- sub. bcx = trans_check_expr( cx, * a) . bcx;
1369
+ sub. bcx = trans_check_expr( cx, a) . bcx;
1361
1370
}
1362
1371
1363
1372
case ( ast. stmt_ret( ?e) ) {
1364
1373
sub. bcx = trans_ret( cx, e) . bcx;
1365
1374
}
1366
1375
1367
1376
case ( ast. stmt_expr( ?e) ) {
1368
- sub. bcx = trans_expr( cx, * e) . bcx;
1377
+ sub. bcx = trans_expr( cx, e) . bcx;
1369
1378
}
1370
1379
1371
1380
case ( ast. stmt_decl( ?d) ) {
@@ -1375,8 +1384,9 @@ impure fn trans_stmt(@block_ctxt cx, &ast.stmt s) -> result {
1375
1384
case ( some[ @ast. expr] ( ?e) ) {
1376
1385
check ( cx. fcx. lllocals. contains_key( local. id) ) ;
1377
1386
auto llptr = cx. fcx. lllocals. get( local. id) ;
1378
- sub = trans_expr( cx, * e) ;
1379
- sub. val = sub. bcx. build. Store ( sub. val, llptr) ;
1387
+ sub = trans_expr( cx, e) ;
1388
+ copy_ty( sub. bcx, true, llptr, sub. val,
1389
+ typeck. expr_ty( e) ) ;
1380
1390
}
1381
1391
}
1382
1392
}
0 commit comments