@@ -865,7 +865,7 @@ fn get_res_dtor(ccx: @crate_ctxt, did: ast::def_id, substs: [ty::t])
865
865
maybe_instantiate_inline ( ccx, did)
866
866
} else { did } ;
867
867
assert did. crate == ast:: local_crate;
868
- monomorphic_fn ( ccx, did, substs, none)
868
+ monomorphic_fn ( ccx, did, substs, none) . val
869
869
}
870
870
871
871
fn trans_res_drop ( bcx : block , rs : ValueRef , did : ast:: def_id ,
@@ -1951,7 +1951,9 @@ enum callee_env {
1951
1951
type lval_maybe_callee = { bcx : block ,
1952
1952
val: ValueRef ,
1953
1953
kind: lval_kind ,
1954
- env: callee_env } ;
1954
+ env: callee_env ,
1955
+ // Tydescs to pass. Only used to call intrinsics
1956
+ tds: option < [ ValueRef ] > } ;
1955
1957
1956
1958
fn null_env_ptr ( bcx : block ) -> ValueRef {
1957
1959
C_null ( T_opaque_box_ptr ( bcx. ccx ( ) ) )
@@ -1970,7 +1972,7 @@ fn lval_temp(bcx: block, val: ValueRef) -> lval_result {
1970
1972
1971
1973
fn lval_no_env ( bcx : block , val : ValueRef , kind : lval_kind )
1972
1974
-> lval_maybe_callee {
1973
- ret { bcx : bcx, val : val, kind : kind, env : is_closure} ;
1975
+ ret { bcx : bcx, val : val, kind : kind, env : is_closure, tds : none } ;
1974
1976
}
1975
1977
1976
1978
fn trans_external_path ( ccx : @crate_ctxt , did : ast:: def_id , t : ty:: t )
@@ -1984,10 +1986,12 @@ fn trans_external_path(ccx: @crate_ctxt, did: ast::def_id, t: ty::t)
1984
1986
}
1985
1987
1986
1988
fn monomorphic_fn ( ccx : @crate_ctxt , fn_id : ast:: def_id , substs : [ ty:: t ] ,
1987
- vtables : option < typeck:: vtable_res > ) -> ValueRef {
1989
+ vtables : option < typeck:: vtable_res > )
1990
+ -> { val : ValueRef , must_cast : bool , intrinsic : bool } {
1991
+ let mut must_cast = false ;
1988
1992
let substs = vec:: map ( substs, { |t|
1989
1993
alt ty:: get ( t) . struct {
1990
- ty:: ty_box ( mt) { ty:: mk_opaque_box ( ccx. tcx ) }
1994
+ ty:: ty_box ( mt) { must_cast = true ; ty:: mk_opaque_box ( ccx. tcx ) }
1991
1995
_ { t }
1992
1996
}
1993
1997
} ) ;
@@ -1996,7 +2000,7 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, substs: [ty::t],
1996
2000
none { no_vts }
1997
2001
} } ;
1998
2002
alt ccx. monomorphized . find ( hash_id) {
1999
- some ( val) { ret val; }
2003
+ some ( val) { ret { val : val , must_cast : must_cast , intrinsic : false } ; }
2000
2004
none { }
2001
2005
}
2002
2006
@@ -2017,9 +2021,11 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, substs: [ty::t],
2017
2021
}
2018
2022
ast_map:: node_variant ( v, _, pt) { ( pt, v. node . name ) }
2019
2023
ast_map:: node_method ( m, _, pt) { ( pt, m. ident ) }
2020
- ast_map:: node_native_item ( _, _ , _) {
2024
+ ast_map:: node_native_item ( _, abi , _) {
2021
2025
// Natives don't have to be monomorphized.
2022
- ret get_item_val ( ccx, fn_id. node ) ;
2026
+ ret { val : get_item_val ( ccx, fn_id. node ) ,
2027
+ must_cast : true ,
2028
+ intrinsic : abi == ast:: native_abi_rust_intrinsic} ;
2023
2029
}
2024
2030
ast_map:: node_ctor ( i) {
2025
2031
alt check ccx. tcx . items . get ( i. id ) {
@@ -2073,7 +2079,7 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, substs: [ty::t],
2073
2079
}
2074
2080
}
2075
2081
}
2076
- lldecl
2082
+ { val : lldecl, must_cast : must_cast , intrinsic : false }
2077
2083
}
2078
2084
2079
2085
fn maybe_instantiate_inline( ccx: @crate_ctxt, fn_id: ast:: def_id)
@@ -2130,11 +2136,20 @@ fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id)
2130
2136
}
2131
2137
}
2132
2138
2139
+ fn add_tydesc_params ( ccx : crate_ctxt , llfty : TypeRef , n : uint ) -> TypeRef {
2140
+ let out_ty = llvm:: LLVMGetReturnType ( llfty) ;
2141
+ let n_args = llvm:: LLVMCountParamTypes ( llfty) ;
2142
+ let args = vec:: init_elt ( n_args as uint , 0 as TypeRef ) ;
2143
+ unsafe { llvm:: LLVMGetParamTypes ( llfty, vec:: unsafe:: to_ptr ( args) ) ; }
2144
+ T_fn ( vec:: slice ( args, 0 u, first_real_arg) +
2145
+ vec:: init_elt ( n, T_ptr ( ccx. tydesc_type ) ) +
2146
+ vec:: tail_n ( args, first_real_arg) , out_ty)
2147
+ }
2148
+
2133
2149
fn lval_static_fn ( bcx : block , fn_id : ast:: def_id , id : ast:: node_id ,
2134
2150
substs : option < ( [ ty:: t ] , typeck:: vtable_res ) > )
2135
2151
-> lval_maybe_callee {
2136
- let ccx = bcx. ccx ( ) ;
2137
- let tcx = ccx. tcx ;
2152
+ let bcx = bcx, ccx = bcx. ccx ( ) , tcx = ccx. tcx ;
2138
2153
let tys = node_id_type_params ( bcx, id) ;
2139
2154
let tpt = ty:: lookup_item_type ( tcx, fn_id) ;
2140
2155
@@ -2151,11 +2166,24 @@ fn lval_static_fn(bcx: block, fn_id: ast::def_id, id: ast::node_id,
2151
2166
impl:: resolve_vtables_in_fn_ctxt ( bcx. fcx , vts) } ) ) }
2152
2167
} ;
2153
2168
if tys. len ( ) > 0 u {
2154
- let val = monomorphic_fn ( ccx, fn_id, tys, vtables) ;
2155
- let cast = PointerCast ( bcx, val, T_ptr ( type_of_fn_from_ty (
2156
- ccx, node_id_type ( bcx, id) ) ) ) ;
2157
- ret { bcx : bcx, val : cast,
2158
- kind : owned, env : null_env} ;
2169
+ let { val, must_cast, intrinsic} = monomorphic_fn ( ccx, fn_id, tys,
2170
+ vtables) ;
2171
+ let tds = none;
2172
+ if intrinsic {
2173
+ tds = some ( vec:: map ( tys, { |t|
2174
+ let ti = none, td_res = get_tydesc ( bcx, t, ti) ;
2175
+ bcx = td_res. bcx ;
2176
+ lazily_emit_all_tydesc_glue ( ccx, ti) ;
2177
+ td_res. val
2178
+ } ) ) ;
2179
+ let llfty = type_of_fn_from_ty ( ccx, node_id_type ( bcx, id) ) ;
2180
+ val = PointerCast ( bcx, val, T_ptr ( add_tydesc_params (
2181
+ ccx, llfty, tys. len ( ) ) ) ) ;
2182
+ } else if must_cast {
2183
+ val = PointerCast ( bcx, val, T_ptr ( type_of_fn_from_ty (
2184
+ ccx, node_id_type ( bcx, id) ) ) ) ;
2185
+ }
2186
+ ret { bcx : bcx, val : val, kind : owned, env : null_env, tds : tds} ;
2159
2187
}
2160
2188
}
2161
2189
@@ -2185,7 +2213,7 @@ fn lval_static_fn(bcx: block, fn_id: ast::def_id, id: ast::node_id,
2185
2213
}
2186
2214
}
2187
2215
2188
- ret { bcx : bcx, val : val, kind : owned, env : null_env} ;
2216
+ ret { bcx : bcx, val : val, kind : owned, env : null_env, tds : none } ;
2189
2217
}
2190
2218
2191
2219
fn lookup_discriminant ( ccx : @crate_ctxt , vid : ast:: def_id ) -> ValueRef {
@@ -2736,6 +2764,11 @@ fn trans_call_inner(in_cx: block, fn_expr_ty: ty::t,
2736
2764
let args_res = trans_args ( bcx, llenv, args, fn_expr_ty, dest) ;
2737
2765
bcx = args_res. bcx ;
2738
2766
let llargs = args_res. args ;
2767
+ option:: may ( f_res. tds ) { |vals|
2768
+ llargs = vec:: slice ( llargs, 0 u, first_real_arg) + vals +
2769
+ vec:: tail_n ( llargs, first_real_arg) ;
2770
+ }
2771
+
2739
2772
let llretslot = args_res. retslot ;
2740
2773
2741
2774
/* If the block is terminated,
0 commit comments