Skip to content

Commit b6ad34b

Browse files
committed
Properly recognize external intrinsics
1 parent e4cbd43 commit b6ad34b

File tree

6 files changed

+89
-65
lines changed

6 files changed

+89
-65
lines changed

src/rustc/metadata/common.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ const tag_mod_impl: uint = 0x30u;
6868

6969
const tag_item_method: uint = 0x31u;
7070
const tag_impl_iface: uint = 0x32u;
71+
const tag_item_is_intrinsic: uint = 0x33u;
7172

7273
// discriminator value for variants
7374
const tag_disr_val: uint = 0x34u;

src/rustc/metadata/csearch.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export get_type;
1919
export get_impl_iface;
2020
export get_impl_method;
2121
export get_item_path;
22+
export item_is_intrinsic;
2223
export maybe_get_item_ast, found_ast, found, found_parent, not_found;
2324

2425
fn get_symbol(cstore: cstore::cstore, def: ast::def_id) -> str {
@@ -134,6 +135,11 @@ fn get_impl_method(cstore: cstore::cstore, def: ast::def_id, mname: str)
134135
decoder::get_impl_method(cdata, def.node, mname)
135136
}
136137

138+
fn item_is_intrinsic(cstore: cstore::cstore, def: ast::def_id) -> bool {
139+
let cdata = cstore::get_crate_data(cstore, def.crate);
140+
decoder::item_is_intrinsic(cdata, def.node)
141+
}
142+
137143
// Local Variables:
138144
// mode: rust
139145
// fill-column: 78;

src/rustc/metadata/decoder.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export get_iface_methods;
3434
export get_crate_module_paths;
3535
export get_item_path;
3636
export maybe_get_item_ast;
37+
export item_is_intrinsic;
3738

3839
// Used internally by astencode:
3940
export translate_def_id;
@@ -272,6 +273,13 @@ fn get_impl_method(cdata: cmd, id: ast::node_id, name: str) -> ast::def_id {
272273
option::get(found)
273274
}
274275

276+
fn item_is_intrinsic(cdata: cmd, id: ast::node_id) -> bool {
277+
let intrinsic = false;
278+
ebml::tagged_docs(lookup_item(id, cdata.data), tag_item_is_intrinsic,
279+
{|_i| intrinsic = true;});
280+
intrinsic
281+
}
282+
275283
fn get_symbol(data: @[u8], id: ast::node_id) -> str {
276284
ret item_symbol(lookup_item(id, data));
277285
}

src/rustc/metadata/encoder.rs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
502502
fn encode_info_for_native_item(ecx: @encode_ctxt, ebml_w: ebml::writer,
503503
nitem: @native_item,
504504
index: @mutable [entry<int>],
505-
path: ast_map::path) {
505+
path: ast_map::path, abi: native_abi) {
506506
if !ecx.reachable.contains_key(nitem.id) { ret; }
507507
*index += [{val: nitem.id, pos: ebml_w.writer.tell()}];
508508

@@ -512,6 +512,10 @@ fn encode_info_for_native_item(ecx: @encode_ctxt, ebml_w: ebml::writer,
512512
encode_def_id(ebml_w, local_def(nitem.id));
513513
encode_family(ebml_w, purity_fn_family(fn_decl.purity));
514514
encode_type_param_bounds(ebml_w, ecx, tps);
515+
if abi == native_abi_rust_intrinsic {
516+
ebml_w.start_tag(tag_item_is_intrinsic);
517+
ebml_w.end_tag();
518+
}
515519
encode_type(ecx, ebml_w, node_id_to_type(ecx.ccx.tcx, nitem.id));
516520
encode_symbol(ecx, ebml_w, nitem.id);
517521
encode_path(ebml_w, path, ast_map::path_name(nitem.ident));
@@ -531,17 +535,19 @@ fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml::writer,
531535
visit_expr: {|_e, _cx, _v|},
532536
visit_item: {|i, cx, v|
533537
visit::visit_item(i, cx, v);
534-
let path = alt check ecx.ccx.tcx.items.get(i.id) {
535-
ast_map::node_item(_, pt) { pt }
536-
};
537-
encode_info_for_item(ecx, ebml_w, i, index, *path);
538+
alt check ecx.ccx.tcx.items.get(i.id) {
539+
ast_map::node_item(_, pt) {
540+
encode_info_for_item(ecx, ebml_w, i, index, *pt);
541+
}
542+
}
538543
},
539544
visit_native_item: {|ni, cx, v|
540545
visit::visit_native_item(ni, cx, v);
541-
let path = alt check ecx.ccx.tcx.items.get(ni.id) {
542-
ast_map::node_native_item(_, _, pt) { pt }
543-
};
544-
encode_info_for_native_item(ecx, ebml_w, ni, index, *path);
546+
alt check ecx.ccx.tcx.items.get(ni.id) {
547+
ast_map::node_native_item(_, abi, pt) {
548+
encode_info_for_native_item(ecx, ebml_w, ni, index, *pt, abi);
549+
}
550+
}
545551
}
546552
with *visit::default_visitor()
547553
}));

src/rustc/middle/trans/base.rs

Lines changed: 51 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2136,21 +2136,44 @@ fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id)
21362136
}
21372137
}
21382138

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, 0u, 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, 0u, 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>)
21512175
-> 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;
21542177
let tpt = ty::lookup_item_type(tcx, fn_id);
21552178

21562179
// 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,
21592182
maybe_instantiate_inline(ccx, fn_id)
21602183
} else { fn_id };
21612184

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() > 0u {
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() > 0u {
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))));
21872192
}
2193+
ret {bcx: bcx, val: val, kind: owned, env: null_env, tds: none};
21882194
}
21892195

21902196
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,
21972203
if tys.len() > 0u {
21982204
// This is supposed to be an external native function.
21992205
// 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+
}
22002209
val = PointerCast(bcx, val, T_ptr(type_of_fn_from_ty(
22012210
ccx, node_id_type(bcx, id))));
22022211
}
@@ -2287,12 +2296,12 @@ fn trans_var(cx: block, def: ast::def, id: ast::node_id, path: @ast::path)
22872296
let ccx = cx.ccx();
22882297
alt def {
22892298
ast::def_fn(did, _) {
2290-
ret lval_static_fn(cx, did, id, none);
2299+
ret lval_static_fn(cx, did, id);
22912300
}
22922301
ast::def_variant(tid, vid) {
22932302
if ty::enum_variant_with_id(ccx.tcx, tid, vid).args.len() > 0u {
22942303
// N-ary variant.
2295-
ret lval_static_fn(cx, vid, id, none);
2304+
ret lval_static_fn(cx, vid, id);
22962305
} else {
22972306
// Nullary variant.
22982307
let enum_ty = node_id_type(cx, id);
@@ -2766,7 +2775,7 @@ fn trans_call_inner(in_cx: block, fn_expr_ty: ty::t,
27662775
let llargs = args_res.args;
27672776
option::may(f_res.tds) {|vals|
27682777
llargs = vec::slice(llargs, 0u, first_real_arg) + vals +
2769-
vec::tail_n(llargs, first_real_arg);
2778+
vec::tailn(llargs, first_real_arg);
27702779
}
27712780

27722781
let llretslot = args_res.retslot;

src/rustc/middle/trans/impl.rs

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ fn trans_method_callee(bcx: block, callee_id: ast::node_id,
4848
-> lval_maybe_callee {
4949
alt origin {
5050
typeck::method_static(did) {
51-
trans_static_callee(bcx, callee_id, self, did, none)
51+
let {bcx, val} = trans_self_arg(bcx, self);
52+
{env: self_env(val, node_id_type(bcx, self.id))
53+
with lval_static_fn(bcx, did, callee_id)}
5254
}
5355
typeck::method_param(iid, off, p, b) {
5456
alt check bcx.fcx.param_substs {
@@ -64,16 +66,6 @@ fn trans_method_callee(bcx: block, callee_id: ast::node_id,
6466
}
6567
}
6668

67-
// Method callee where the method is statically known
68-
fn trans_static_callee(bcx: block, callee_id: ast::node_id,
69-
base: @ast::expr, did: ast::def_id,
70-
substs: option<([ty::t], typeck::vtable_res)>)
71-
-> lval_maybe_callee {
72-
let {bcx, val} = trans_self_arg(bcx, base);
73-
{env: self_env(val, node_id_type(bcx, base.id))
74-
with lval_static_fn(bcx, did, callee_id, substs)}
75-
}
76-
7769
fn trans_vtable_callee(bcx: block, env: callee_env, vtable: ValueRef,
7870
callee_id: ast::node_id, n_method: uint)
7971
-> lval_maybe_callee {
@@ -122,11 +114,13 @@ fn trans_monomorphized_callee(bcx: block, callee_id: ast::node_id,
122114
let node_substs = node_id_type_params(bcx, callee_id);
123115
let ty_substs = impl_substs +
124116
vec::tailn(node_substs, node_substs.len() - n_m_tps);
125-
ret trans_static_callee(bcx, callee_id, base, mth_id,
126-
some((ty_substs, sub_origins)));
117+
let {bcx, val} = trans_self_arg(bcx, base);
118+
{env: self_env(val, node_id_type(bcx, base.id))
119+
with lval_static_fn_inner(bcx, mth_id, callee_id, ty_substs,
120+
some(sub_origins))}
127121
}
128122
typeck::vtable_iface(iid, tps) {
129-
ret trans_iface_callee(bcx, base, callee_id, n_method);
123+
trans_iface_callee(bcx, base, callee_id, n_method)
130124
}
131125
typeck::vtable_param(n_param, n_bound) {
132126
fail "vtable_param left in monomorphized function's vtable substs";

0 commit comments

Comments
 (0)