@@ -1120,12 +1120,16 @@ fn declare_tydesc(cx: &@local_ctxt, sp: &span, t: &ty::t, ty_params: &[uint])
1120
1120
mutable drop_glue: none :: < ValueRef > ,
1121
1121
mutable free_glue: none :: < ValueRef > ,
1122
1122
mutable cmp_glue: none :: < ValueRef > ,
1123
+ mutable copy_glue: none :: < ValueRef > ,
1123
1124
ty_params: ty_params} ;
1124
1125
log "--- declare_tydesc " + ty_to_str ( cx. ccx . tcx , t) ;
1125
1126
ret info;
1126
1127
}
1127
1128
1128
- type make_generic_glue_helper_fn = fn ( & @block_ctxt , ValueRef , & ty:: t ) ;
1129
+ tag glue_helper {
1130
+ default_helper( fn ( & @block_ctxt, ValueRef , & ty:: t) ) ;
1131
+ copy_helper ( fn ( & @block_ctxt, ValueRef , ValueRef , & ty:: t) ) ;
1132
+ }
1129
1133
1130
1134
fn declare_generic_glue ( cx : & @local_ctxt , t : & ty:: t , llfnty : TypeRef ,
1131
1135
name : & str ) -> ValueRef {
@@ -1141,7 +1145,7 @@ fn declare_generic_glue(cx: &@local_ctxt, t: &ty::t, llfnty: TypeRef,
1141
1145
1142
1146
fn make_generic_glue_inner ( cx : & @local_ctxt , sp : & span , t : & ty:: t ,
1143
1147
llfn : ValueRef ,
1144
- helper : & make_generic_glue_helper_fn ,
1148
+ helper : & glue_helper ,
1145
1149
ty_params : & [ uint ] ) -> ValueRef {
1146
1150
let fcx = new_fn_ctxt ( cx, sp, llfn) ;
1147
1151
llvm:: LLVMSetLinkage ( llfn,
@@ -1177,13 +1181,22 @@ fn make_generic_glue_inner(cx: &@local_ctxt, sp: &span, t: &ty::t,
1177
1181
let lltop = bcx. llbb ;
1178
1182
let llrawptr0 = llvm:: LLVMGetParam ( llfn, 4 u) ;
1179
1183
let llval0 = bcx. build . BitCast ( llrawptr0, llty) ;
1180
- helper ( bcx, llval0, t) ;
1184
+ alt helper {
1185
+ default_helper( helper) {
1186
+ helper ( bcx, llval0, t) ;
1187
+ }
1188
+ copy_helper ( helper) {
1189
+ let llrawptr1 = llvm:: LLVMGetParam ( llfn, 4 u) ;
1190
+ let llval1 = bcx. build . BitCast ( llrawptr1, llty) ;
1191
+ helper ( bcx, llval0, llval1, t) ;
1192
+ }
1193
+ }
1181
1194
finish_fn ( fcx, lltop) ;
1182
1195
ret llfn;
1183
1196
}
1184
1197
1185
1198
fn make_generic_glue ( cx : & @local_ctxt , sp : & span , t : & ty:: t , llfn : ValueRef ,
1186
- helper : & make_generic_glue_helper_fn , ty_params : & [ uint ] ,
1199
+ helper : & glue_helper , ty_params : & [ uint ] ,
1187
1200
name : & str ) -> ValueRef {
1188
1201
if !cx. ccx . sess . get_opts ( ) . stats {
1189
1202
ret make_generic_glue_inner ( cx, sp, t, llfn, helper, ty_params) ;
@@ -1201,6 +1214,7 @@ fn emit_tydescs(ccx: &@crate_ctxt) {
1201
1214
for each pair: @{ key : ty:: t, val : @tydesc_info} in ccx. tydescs . items ( ) {
1202
1215
let glue_fn_ty = T_ptr ( T_glue_fn ( * ccx) ) ;
1203
1216
let cmp_fn_ty = T_ptr ( T_cmp_glue_fn ( * ccx) ) ;
1217
+ let copy_fn_ty = T_ptr ( T_copy_glue_fn ( * ccx) ) ;
1204
1218
let ti = pair. val ;
1205
1219
let take_glue =
1206
1220
alt { ti. take_glue } {
@@ -1222,6 +1236,11 @@ fn emit_tydescs(ccx: &@crate_ctxt) {
1222
1236
none. { ccx . stats . n_null_glues += 1 u; C_null ( cmp_fn_ty) }
1223
1237
some ( v) { ccx. stats . n_real_glues += 1 u; v }
1224
1238
} ;
1239
+ let copy_glue =
1240
+ alt { ti. copy_glue } {
1241
+ none. { ccx . stats . n_null_glues += 1 u; C_null ( copy_fn_ty) }
1242
+ some ( v) { ccx. stats . n_real_glues += 1 u; v }
1243
+ } ;
1225
1244
1226
1245
let shape = shape:: shape_of ( ccx, pair. key ) ;
1227
1246
let shape_tables =
@@ -1236,9 +1255,9 @@ fn emit_tydescs(ccx: &@crate_ctxt) {
1236
1255
take_glue, // take_glue
1237
1256
drop_glue, // drop_glue
1238
1257
free_glue, // free_glue
1258
+ copy_glue, // copy_glue
1239
1259
C_null ( glue_fn_ty) , // sever_glue
1240
1260
C_null ( glue_fn_ty) , // mark_glue
1241
- C_null ( glue_fn_ty) , // obj_drop_glue
1242
1261
C_null ( glue_fn_ty) , // is_stateful
1243
1262
cmp_glue, // cmp_glue
1244
1263
C_shape ( ccx, shape) , // shape
@@ -1253,6 +1272,11 @@ fn emit_tydescs(ccx: &@crate_ctxt) {
1253
1272
}
1254
1273
}
1255
1274
1275
+ fn make_copy_glue ( cx : & @block_ctxt , dst : ValueRef , src : ValueRef , t : & ty:: t ) {
1276
+ let bcx = memmove_ty ( cx, dst, src, t) . bcx ;
1277
+ build_return ( bcx) ;
1278
+ }
1279
+
1256
1280
fn make_take_glue ( cx : & @block_ctxt , v : ValueRef , t : & ty:: t ) {
1257
1281
// NB: v is an *alias* of type t here, not a direct value.
1258
1282
@@ -1970,6 +1994,7 @@ fn lazily_emit_all_tydesc_glue(cx: &@block_ctxt,
1970
1994
lazily_emit_tydesc_glue ( cx, abi:: tydesc_field_drop_glue, static_ti) ;
1971
1995
lazily_emit_tydesc_glue ( cx, abi:: tydesc_field_free_glue, static_ti) ;
1972
1996
lazily_emit_tydesc_glue ( cx, abi:: tydesc_field_cmp_glue, static_ti) ;
1997
+ lazily_emit_tydesc_glue ( cx, abi:: tydesc_field_copy_glue, static_ti) ;
1973
1998
}
1974
1999
1975
2000
fn lazily_emit_all_generic_info_tydesc_glues ( cx : & @block_ctxt ,
@@ -1995,7 +2020,8 @@ fn lazily_emit_tydesc_glue(cx: &@block_ctxt, field: int,
1995
2020
declare_generic_glue ( lcx, ti. ty , T_glue_fn ( * lcx. ccx ) ,
1996
2021
"take" ) ;
1997
2022
ti. take_glue = some :: < ValueRef > ( glue_fn) ;
1998
- make_generic_glue ( lcx, cx. sp , ti. ty , glue_fn, make_take_glue,
2023
+ make_generic_glue ( lcx, cx. sp , ti. ty , glue_fn,
2024
+ default_helper ( make_take_glue) ,
1999
2025
ti. ty_params , "take" ) ;
2000
2026
log #fmt[ "--- lazily_emit_tydesc_glue TAKE %s" ,
2001
2027
ty_to_str ( bcx_tcx ( cx) , ti. ty ) ] ;
@@ -2012,13 +2038,14 @@ fn lazily_emit_tydesc_glue(cx: &@block_ctxt, field: int,
2012
2038
declare_generic_glue ( lcx, ti. ty , T_glue_fn ( * lcx. ccx ) ,
2013
2039
"drop" ) ;
2014
2040
ti. drop_glue = some :: < ValueRef > ( glue_fn) ;
2015
- make_generic_glue ( lcx, cx. sp , ti. ty , glue_fn, make_drop_glue,
2041
+ make_generic_glue ( lcx, cx. sp , ti. ty , glue_fn,
2042
+ default_helper ( make_drop_glue) ,
2016
2043
ti. ty_params , "drop" ) ;
2017
2044
log #fmt[ "--- lazily_emit_tydesc_glue DROP %s" ,
2018
2045
ty_to_str ( bcx_tcx ( cx) , ti. ty ) ] ;
2019
2046
}
2020
2047
}
2021
- } else if field == abi:: tydesc_field_free_glue {
2048
+ } else if field == abi:: tydesc_field_free_glue {
2022
2049
alt { ti. free_glue } {
2023
2050
some ( _) { }
2024
2051
none. {
@@ -2029,7 +2056,8 @@ fn lazily_emit_tydesc_glue(cx: &@block_ctxt, field: int,
2029
2056
declare_generic_glue ( lcx, ti. ty , T_glue_fn ( * lcx. ccx ) ,
2030
2057
"free" ) ;
2031
2058
ti. free_glue = some :: < ValueRef > ( glue_fn) ;
2032
- make_generic_glue ( lcx, cx. sp , ti. ty , glue_fn, make_free_glue,
2059
+ make_generic_glue ( lcx, cx. sp , ti. ty , glue_fn,
2060
+ default_helper ( make_free_glue) ,
2033
2061
ti. ty_params , "free" ) ;
2034
2062
log #fmt[ "--- lazily_emit_tydesc_glue FREE %s" ,
2035
2063
ty_to_str ( bcx_tcx ( cx) , ti. ty ) ] ;
@@ -2046,6 +2074,21 @@ fn lazily_emit_tydesc_glue(cx: &@block_ctxt, field: int,
2046
2074
ty_to_str ( bcx_tcx ( cx) , ti. ty ) ] ;
2047
2075
}
2048
2076
}
2077
+ } else if field == abi:: tydesc_field_copy_glue {
2078
+ alt { ti. copy_glue } {
2079
+ some ( _) { }
2080
+ none. {
2081
+ let lcx = cx. fcx . lcx ;
2082
+ let glue_fn =
2083
+ declare_generic_glue ( lcx, ti. ty , T_copy_glue_fn ( * lcx. ccx ) ,
2084
+ "copy" ) ;
2085
+ ti. copy_glue = some ( glue_fn) ;
2086
+ make_generic_glue ( lcx, cx. sp , ti. ty , glue_fn,
2087
+ copy_helper ( make_copy_glue) ,
2088
+ ti. ty_params , "copy" ) ;
2089
+
2090
+ }
2091
+ }
2049
2092
}
2050
2093
}
2051
2094
}
@@ -2065,8 +2108,6 @@ fn call_tydesc_glue_full(cx: &@block_ctxt, v: ValueRef, tydesc: ValueRef,
2065
2108
static_glue_fn = sti. drop_glue ;
2066
2109
} else if field == abi:: tydesc_field_free_glue {
2067
2110
static_glue_fn = sti. free_glue ;
2068
- } else if field == abi:: tydesc_field_cmp_glue {
2069
- static_glue_fn = sti. cmp_glue ;
2070
2111
}
2071
2112
}
2072
2113
}
@@ -2787,6 +2828,7 @@ mod ivec {
2787
2828
lazily_emit_tydesc_glue ( bcx, abi:: tydesc_field_take_glue, none) ;
2788
2829
lazily_emit_tydesc_glue ( bcx, abi:: tydesc_field_drop_glue, none) ;
2789
2830
lazily_emit_tydesc_glue ( bcx, abi:: tydesc_field_free_glue, none) ;
2831
+ lazily_emit_tydesc_glue ( bcx, abi:: tydesc_field_copy_glue, none) ;
2790
2832
let rhs_len_and_data = get_len_and_data ( bcx, rhs, unit_ty) ;
2791
2833
let rhs_len = rhs_len_and_data. len ;
2792
2834
let rhs_data = rhs_len_and_data. data ;
0 commit comments