diff options
| author | Marijn Haverbeke <marijnh@gmail.com> | 2012-03-09 13:35:20 +0100 |
|---|---|---|
| committer | Marijn Haverbeke <marijnh@gmail.com> | 2012-03-15 10:22:46 +0100 |
| commit | b6ad34bef4f0b3613d51557cd327055a2c5311fd (patch) | |
| tree | 9d94307570687aedc031e0e8b8b16a6b8cd4f9fc /src/rustc | |
| parent | e4cbd43c430ef0d5f63ca7cb86a65a618521e175 (diff) | |
| download | rust-b6ad34bef4f0b3613d51557cd327055a2c5311fd.tar.gz rust-b6ad34bef4f0b3613d51557cd327055a2c5311fd.zip | |
Properly recognize external intrinsics
Diffstat (limited to 'src/rustc')
| -rw-r--r-- | src/rustc/metadata/common.rs | 1 | ||||
| -rw-r--r-- | src/rustc/metadata/csearch.rs | 6 | ||||
| -rw-r--r-- | src/rustc/metadata/decoder.rs | 8 | ||||
| -rw-r--r-- | src/rustc/metadata/encoder.rs | 24 | ||||
| -rw-r--r-- | src/rustc/middle/trans/base.rs | 93 | ||||
| -rw-r--r-- | src/rustc/middle/trans/impl.rs | 22 |
6 files changed, 89 insertions, 65 deletions
diff --git a/src/rustc/metadata/common.rs b/src/rustc/metadata/common.rs index db3dc4078ed..88800e17aff 100644 --- a/src/rustc/metadata/common.rs +++ b/src/rustc/metadata/common.rs @@ -68,6 +68,7 @@ const tag_mod_impl: uint = 0x30u; const tag_item_method: uint = 0x31u; const tag_impl_iface: uint = 0x32u; +const tag_item_is_intrinsic: uint = 0x33u; // discriminator value for variants const tag_disr_val: uint = 0x34u; diff --git a/src/rustc/metadata/csearch.rs b/src/rustc/metadata/csearch.rs index 6be4124d5e6..08836703836 100644 --- a/src/rustc/metadata/csearch.rs +++ b/src/rustc/metadata/csearch.rs @@ -19,6 +19,7 @@ export get_type; export get_impl_iface; export get_impl_method; export get_item_path; +export item_is_intrinsic; export maybe_get_item_ast, found_ast, found, found_parent, not_found; 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) decoder::get_impl_method(cdata, def.node, mname) } +fn item_is_intrinsic(cstore: cstore::cstore, def: ast::def_id) -> bool { + let cdata = cstore::get_crate_data(cstore, def.crate); + decoder::item_is_intrinsic(cdata, def.node) +} + // Local Variables: // mode: rust // fill-column: 78; diff --git a/src/rustc/metadata/decoder.rs b/src/rustc/metadata/decoder.rs index ac6e32f292d..70c771b85c1 100644 --- a/src/rustc/metadata/decoder.rs +++ b/src/rustc/metadata/decoder.rs @@ -34,6 +34,7 @@ export get_iface_methods; export get_crate_module_paths; export get_item_path; export maybe_get_item_ast; +export item_is_intrinsic; // Used internally by astencode: export translate_def_id; @@ -272,6 +273,13 @@ fn get_impl_method(cdata: cmd, id: ast::node_id, name: str) -> ast::def_id { option::get(found) } +fn item_is_intrinsic(cdata: cmd, id: ast::node_id) -> bool { + let intrinsic = false; + ebml::tagged_docs(lookup_item(id, cdata.data), tag_item_is_intrinsic, + {|_i| intrinsic = true;}); + intrinsic +} + fn get_symbol(data: @[u8], id: ast::node_id) -> str { ret item_symbol(lookup_item(id, data)); } diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs index 57813f1791b..fee50a927e6 100644 --- a/src/rustc/metadata/encoder.rs +++ b/src/rustc/metadata/encoder.rs @@ -502,7 +502,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, fn encode_info_for_native_item(ecx: @encode_ctxt, ebml_w: ebml::writer, nitem: @native_item, index: @mutable [entry<int>], - path: ast_map::path) { + path: ast_map::path, abi: native_abi) { if !ecx.reachable.contains_key(nitem.id) { ret; } *index += [{val: nitem.id, pos: ebml_w.writer.tell()}]; @@ -512,6 +512,10 @@ fn encode_info_for_native_item(ecx: @encode_ctxt, ebml_w: ebml::writer, encode_def_id(ebml_w, local_def(nitem.id)); encode_family(ebml_w, purity_fn_family(fn_decl.purity)); encode_type_param_bounds(ebml_w, ecx, tps); + if abi == native_abi_rust_intrinsic { + ebml_w.start_tag(tag_item_is_intrinsic); + ebml_w.end_tag(); + } encode_type(ecx, ebml_w, node_id_to_type(ecx.ccx.tcx, nitem.id)); encode_symbol(ecx, ebml_w, nitem.id); 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, visit_expr: {|_e, _cx, _v|}, visit_item: {|i, cx, v| visit::visit_item(i, cx, v); - let path = alt check ecx.ccx.tcx.items.get(i.id) { - ast_map::node_item(_, pt) { pt } - }; - encode_info_for_item(ecx, ebml_w, i, index, *path); + alt check ecx.ccx.tcx.items.get(i.id) { + ast_map::node_item(_, pt) { + encode_info_for_item(ecx, ebml_w, i, index, *pt); + } + } }, visit_native_item: {|ni, cx, v| visit::visit_native_item(ni, cx, v); - let path = alt check ecx.ccx.tcx.items.get(ni.id) { - ast_map::node_native_item(_, _, pt) { pt } - }; - encode_info_for_native_item(ecx, ebml_w, ni, index, *path); + alt check ecx.ccx.tcx.items.get(ni.id) { + ast_map::node_native_item(_, abi, pt) { + encode_info_for_native_item(ecx, ebml_w, ni, index, *pt, abi); + } + } } with *visit::default_visitor() })); diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index 0ea5408c8ed..f81c24d811e 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -2136,21 +2136,44 @@ fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id) } } -fn add_tydesc_params(ccx: crate_ctxt, llfty: TypeRef, n: uint) -> TypeRef { - let out_ty = llvm::LLVMGetReturnType(llfty); - let n_args = llvm::LLVMCountParamTypes(llfty); - let args = vec::init_elt(n_args as uint, 0 as TypeRef); - unsafe { llvm::LLVMGetParamTypes(llfty, vec::unsafe::to_ptr(args)); } - T_fn(vec::slice(args, 0u, first_real_arg) + - vec::init_elt(n, T_ptr(ccx.tydesc_type)) + - vec::tail_n(args, first_real_arg), out_ty) -} - -fn lval_static_fn(bcx: block, fn_id: ast::def_id, id: ast::node_id, - substs: option<([ty::t], typeck::vtable_res)>) +fn lval_intrinsic_fn(bcx: block, val: ValueRef, tys: [ty::t], + id: ast::node_id) -> lval_maybe_callee { + fn add_tydesc_params(ccx: @crate_ctxt, llfty: TypeRef, n: uint) + -> TypeRef { + let out_ty = llvm::LLVMGetReturnType(llfty); + let n_args = llvm::LLVMCountParamTypes(llfty); + let args = vec::from_elem(n_args as uint, 0 as TypeRef); + unsafe { llvm::LLVMGetParamTypes(llfty, vec::unsafe::to_ptr(args)); } + T_fn(vec::slice(args, 0u, first_real_arg) + + vec::from_elem(n, T_ptr(ccx.tydesc_type)) + + vec::tailn(args, first_real_arg), out_ty) + } + + let bcx = bcx, ccx = bcx.ccx(); + let tds = vec::map(tys, {|t| + let ti = none, td_res = get_tydesc(bcx, t, ti); + bcx = td_res.bcx; + lazily_emit_all_tydesc_glue(ccx, ti); + td_res.val + }); + let llfty = type_of_fn_from_ty(ccx, node_id_type(bcx, id)); + let val = PointerCast(bcx, val, T_ptr(add_tydesc_params( + ccx, llfty, tys.len()))); + {bcx: bcx, val: val, kind: owned, env: null_env, tds: some(tds)} +} + +fn lval_static_fn(bcx: block, fn_id: ast::def_id, id: ast::node_id) + -> lval_maybe_callee { + let vts = option::map(bcx.ccx().maps.vtable_map.find(id), {|vts| + impl::resolve_vtables_in_fn_ctxt(bcx.fcx, vts) + }); + lval_static_fn_inner(bcx, fn_id, id, node_id_type_params(bcx, id), vts) +} + +fn lval_static_fn_inner(bcx: block, fn_id: ast::def_id, id: ast::node_id, + tys: [ty::t], vtables: option<typeck::vtable_res>) -> lval_maybe_callee { - let bcx = bcx, ccx = bcx.ccx(), tcx = ccx.tcx; - let tys = node_id_type_params(bcx, id); + let ccx = bcx.ccx(), tcx = ccx.tcx; let tpt = ty::lookup_item_type(tcx, fn_id); // 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, maybe_instantiate_inline(ccx, fn_id) } else { fn_id }; - if fn_id.crate == ast::local_crate { - let (tys, vtables) = alt substs { - some((tys, vts)) { (tys, some(vts)) } - none { (tys, option::map(ccx.maps.vtable_map.find(id), {|vts| - impl::resolve_vtables_in_fn_ctxt(bcx.fcx, vts)})) } - }; - if tys.len() > 0u { - let {val, must_cast, intrinsic} = monomorphic_fn(ccx, fn_id, tys, - vtables); - let tds = none; - if intrinsic { - tds = some(vec::map(tys, {|t| - let ti = none, td_res = get_tydesc(bcx, t, ti); - bcx = td_res.bcx; - lazily_emit_all_tydesc_glue(ccx, ti); - td_res.val - })); - let llfty = type_of_fn_from_ty(ccx, node_id_type(bcx, id)); - val = PointerCast(bcx, val, T_ptr(add_tydesc_params( - ccx, llfty, tys.len()))); - } else if must_cast { - val = PointerCast(bcx, val, T_ptr(type_of_fn_from_ty( - ccx, node_id_type(bcx, id)))); - } - ret {bcx: bcx, val: val, kind: owned, env: null_env, tds: tds}; + if fn_id.crate == ast::local_crate && tys.len() > 0u { + let {val, must_cast, intrinsic} = monomorphic_fn(ccx, fn_id, tys, + vtables); + if intrinsic { ret lval_intrinsic_fn(bcx, val, tys, id); } + if must_cast { + val = PointerCast(bcx, val, T_ptr(type_of_fn_from_ty( + ccx, node_id_type(bcx, id)))); } + ret {bcx: bcx, val: val, kind: owned, env: null_env, tds: none}; } 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, if tys.len() > 0u { // This is supposed to be an external native function. // Unfortunately, I found no easy/cheap way to assert that. + if csearch::item_is_intrinsic(ccx.sess.cstore, fn_id) { + ret lval_intrinsic_fn(bcx, val, tys, id); + } val = PointerCast(bcx, val, T_ptr(type_of_fn_from_ty( ccx, node_id_type(bcx, id)))); } @@ -2287,12 +2296,12 @@ fn trans_var(cx: block, def: ast::def, id: ast::node_id, path: @ast::path) let ccx = cx.ccx(); alt def { ast::def_fn(did, _) { - ret lval_static_fn(cx, did, id, none); + ret lval_static_fn(cx, did, id); } ast::def_variant(tid, vid) { if ty::enum_variant_with_id(ccx.tcx, tid, vid).args.len() > 0u { // N-ary variant. - ret lval_static_fn(cx, vid, id, none); + ret lval_static_fn(cx, vid, id); } else { // Nullary variant. let enum_ty = node_id_type(cx, id); @@ -2766,7 +2775,7 @@ fn trans_call_inner(in_cx: block, fn_expr_ty: ty::t, let llargs = args_res.args; option::may(f_res.tds) {|vals| llargs = vec::slice(llargs, 0u, first_real_arg) + vals + - vec::tail_n(llargs, first_real_arg); + vec::tailn(llargs, first_real_arg); } let llretslot = args_res.retslot; diff --git a/src/rustc/middle/trans/impl.rs b/src/rustc/middle/trans/impl.rs index 00782c0a11b..3486de0dc90 100644 --- a/src/rustc/middle/trans/impl.rs +++ b/src/rustc/middle/trans/impl.rs @@ -48,7 +48,9 @@ fn trans_method_callee(bcx: block, callee_id: ast::node_id, -> lval_maybe_callee { alt origin { typeck::method_static(did) { - trans_static_callee(bcx, callee_id, self, did, none) + let {bcx, val} = trans_self_arg(bcx, self); + {env: self_env(val, node_id_type(bcx, self.id)) + with lval_static_fn(bcx, did, callee_id)} } typeck::method_param(iid, off, p, b) { alt check bcx.fcx.param_substs { @@ -64,16 +66,6 @@ fn trans_method_callee(bcx: block, callee_id: ast::node_id, } } -// Method callee where the method is statically known -fn trans_static_callee(bcx: block, callee_id: ast::node_id, - base: @ast::expr, did: ast::def_id, - substs: option<([ty::t], typeck::vtable_res)>) - -> lval_maybe_callee { - let {bcx, val} = trans_self_arg(bcx, base); - {env: self_env(val, node_id_type(bcx, base.id)) - with lval_static_fn(bcx, did, callee_id, substs)} -} - fn trans_vtable_callee(bcx: block, env: callee_env, vtable: ValueRef, callee_id: ast::node_id, n_method: uint) -> lval_maybe_callee { @@ -122,11 +114,13 @@ fn trans_monomorphized_callee(bcx: block, callee_id: ast::node_id, let node_substs = node_id_type_params(bcx, callee_id); let ty_substs = impl_substs + vec::tailn(node_substs, node_substs.len() - n_m_tps); - ret trans_static_callee(bcx, callee_id, base, mth_id, - some((ty_substs, sub_origins))); + let {bcx, val} = trans_self_arg(bcx, base); + {env: self_env(val, node_id_type(bcx, base.id)) + with lval_static_fn_inner(bcx, mth_id, callee_id, ty_substs, + some(sub_origins))} } typeck::vtable_iface(iid, tps) { - ret trans_iface_callee(bcx, base, callee_id, n_method); + trans_iface_callee(bcx, base, callee_id, n_method) } typeck::vtable_param(n_param, n_bound) { fail "vtable_param left in monomorphized function's vtable substs"; |
