@@ -2136,21 +2136,44 @@ fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id)
2136
2136
}
2137
2137
}
2138
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
-
2149
- fn lval_static_fn ( bcx : block , fn_id : ast:: def_id , id : ast:: node_id ,
2150
- substs : option < ( [ ty:: t ] , typeck:: vtable_res ) > )
2139
+ fn lval_intrinsic_fn ( bcx : block , val : ValueRef , tys : [ ty:: t ] ,
2140
+ id : ast:: node_id ) -> lval_maybe_callee {
2141
+ fn add_tydesc_params ( ccx : @crate_ctxt , llfty : TypeRef , n : uint )
2142
+ -> TypeRef {
2143
+ let out_ty = llvm:: LLVMGetReturnType ( llfty) ;
2144
+ let n_args = llvm:: LLVMCountParamTypes ( llfty) ;
2145
+ let args = vec:: from_elem ( n_args as uint , 0 as TypeRef ) ;
2146
+ unsafe { llvm:: LLVMGetParamTypes ( llfty, vec:: unsafe:: to_ptr ( args) ) ; }
2147
+ T_fn ( vec:: slice ( args, 0 u, first_real_arg) +
2148
+ vec:: from_elem ( n, T_ptr ( ccx. tydesc_type ) ) +
2149
+ vec:: tailn ( args, first_real_arg) , out_ty)
2150
+ }
2151
+
2152
+ let bcx = bcx, ccx = bcx. ccx ( ) ;
2153
+ let tds = vec:: map ( tys, { |t|
2154
+ let ti = none, td_res = get_tydesc ( bcx, t, ti) ;
2155
+ bcx = td_res. bcx ;
2156
+ lazily_emit_all_tydesc_glue ( ccx, ti) ;
2157
+ td_res. val
2158
+ } ) ;
2159
+ let llfty = type_of_fn_from_ty ( ccx, node_id_type ( bcx, id) ) ;
2160
+ let val = PointerCast ( bcx, val, T_ptr ( add_tydesc_params (
2161
+ ccx, llfty, tys. len ( ) ) ) ) ;
2162
+ { bcx: bcx, val: val, kind: owned, env: null_env, tds: some ( tds) }
2163
+ }
2164
+
2165
+ fn lval_static_fn ( bcx : block , fn_id : ast:: def_id , id : ast:: node_id )
2166
+ -> lval_maybe_callee {
2167
+ let vts = option:: map ( bcx. ccx ( ) . maps . vtable_map . find ( id) , { |vts|
2168
+ impl:: resolve_vtables_in_fn_ctxt ( bcx. fcx , vts)
2169
+ } ) ;
2170
+ lval_static_fn_inner ( bcx, fn_id, id, node_id_type_params ( bcx, id) , vts)
2171
+ }
2172
+
2173
+ fn lval_static_fn_inner ( bcx : block , fn_id : ast:: def_id , id : ast:: node_id ,
2174
+ tys : [ ty:: t ] , vtables : option < typeck:: vtable_res > )
2151
2175
-> lval_maybe_callee {
2152
- let bcx = bcx, ccx = bcx. ccx ( ) , tcx = ccx. tcx ;
2153
- let tys = node_id_type_params ( bcx, id) ;
2176
+ let ccx = bcx. ccx ( ) , tcx = ccx. tcx ;
2154
2177
let tpt = ty:: lookup_item_type ( tcx, fn_id) ;
2155
2178
2156
2179
// Check whether this fn has an inlined copy and, if so, redirect fn_id to
@@ -2159,32 +2182,15 @@ fn lval_static_fn(bcx: block, fn_id: ast::def_id, id: ast::node_id,
2159
2182
maybe_instantiate_inline ( ccx, fn_id)
2160
2183
} else { fn_id } ;
2161
2184
2162
- if fn_id. crate == ast:: local_crate {
2163
- let ( tys, vtables) = alt substs {
2164
- some( ( tys, vts) ) { ( tys, some ( vts) ) }
2165
- none { ( tys, option:: map ( ccx. maps . vtable_map . find ( id) , { |vts|
2166
- impl:: resolve_vtables_in_fn_ctxt ( bcx. fcx , vts) } ) ) }
2167
- } ;
2168
- if tys. len ( ) > 0 u {
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} ;
2185
+ if fn_id. crate == ast:: local_crate && tys. len ( ) > 0 u {
2186
+ let { val, must_cast, intrinsic} = monomorphic_fn ( ccx, fn_id, tys,
2187
+ vtables) ;
2188
+ if intrinsic { ret lval_intrinsic_fn ( bcx, val, tys, id) ; }
2189
+ if must_cast {
2190
+ val = PointerCast ( bcx, val, T_ptr ( type_of_fn_from_ty (
2191
+ ccx, node_id_type ( bcx, id) ) ) ) ;
2187
2192
}
2193
+ ret { bcx : bcx, val : val, kind : owned, env : null_env, tds : none} ;
2188
2194
}
2189
2195
2190
2196
let val = if fn_id. crate == ast:: local_crate {
@@ -2197,6 +2203,9 @@ fn lval_static_fn(bcx: block, fn_id: ast::def_id, id: ast::node_id,
2197
2203
if tys. len ( ) > 0 u {
2198
2204
// This is supposed to be an external native function.
2199
2205
// Unfortunately, I found no easy/cheap way to assert that.
2206
+ if csearch:: item_is_intrinsic ( ccx. sess . cstore , fn_id) {
2207
+ ret lval_intrinsic_fn ( bcx, val, tys, id) ;
2208
+ }
2200
2209
val = PointerCast ( bcx, val, T_ptr ( type_of_fn_from_ty (
2201
2210
ccx, node_id_type ( bcx, id) ) ) ) ;
2202
2211
}
@@ -2287,12 +2296,12 @@ fn trans_var(cx: block, def: ast::def, id: ast::node_id, path: @ast::path)
2287
2296
let ccx = cx. ccx ( ) ;
2288
2297
alt def {
2289
2298
ast : : def_fn ( did, _) {
2290
- ret lval_static_fn ( cx, did, id, none ) ;
2299
+ ret lval_static_fn ( cx, did, id) ;
2291
2300
}
2292
2301
ast:: def_variant ( tid, vid) {
2293
2302
if ty:: enum_variant_with_id ( ccx. tcx , tid, vid) . args . len ( ) > 0 u {
2294
2303
// N-ary variant.
2295
- ret lval_static_fn ( cx, vid, id, none ) ;
2304
+ ret lval_static_fn ( cx, vid, id) ;
2296
2305
} else {
2297
2306
// Nullary variant.
2298
2307
let enum_ty = node_id_type ( cx, id) ;
@@ -2766,7 +2775,7 @@ fn trans_call_inner(in_cx: block, fn_expr_ty: ty::t,
2766
2775
let llargs = args_res. args ;
2767
2776
option:: may ( f_res. tds ) { |vals|
2768
2777
llargs = vec:: slice ( llargs, 0 u, first_real_arg) + vals +
2769
- vec:: tail_n ( llargs, first_real_arg) ;
2778
+ vec:: tailn ( llargs, first_real_arg) ;
2770
2779
}
2771
2780
2772
2781
let llretslot = args_res. retslot ;
0 commit comments