Skip to content

Commit ea2e379

Browse files
committed
Implement built-in native modules as an alternative to intrinsics
Issue #1981
1 parent 73a0c17 commit ea2e379

File tree

16 files changed

+195
-57
lines changed

16 files changed

+195
-57
lines changed

src/rustc/front/attr.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,9 @@ fn native_abi(attrs: [ast::attribute]) -> either<str, ast::native_abi> {
240240
option::some("rust-intrinsic") {
241241
either::right(ast::native_abi_rust_intrinsic)
242242
}
243+
option::some("rust-builtin") {
244+
either::right(ast::native_abi_rust_builtin)
245+
}
243246
option::some("cdecl") {
244247
either::right(ast::native_abi_cdecl)
245248
}

src/rustc/metadata/astencode.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,9 @@ fn simplify_ast(ii: ast::inlined_item) -> ast::inlined_item {
374374
ast::ii_method(d, m) {
375375
ast::ii_method(d, fld.fold_method(m))
376376
}
377+
ast::ii_native(i) {
378+
ast::ii_native(fld.fold_native_item(i))
379+
}
377380
}
378381
}
379382

@@ -398,6 +401,9 @@ fn renumber_ast(xcx: extended_decode_ctxt, ii: ast::inlined_item)
398401
ast::ii_method(d, m) {
399402
ast::ii_method(xcx.tr_def_id(d), fld.fold_method(m))
400403
}
404+
ast::ii_native(i) {
405+
ast::ii_native(fld.fold_native_item(i))
406+
}
401407
}
402408
}
403409

src/rustc/metadata/encoder.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,12 @@ fn encode_info_for_native_item(ecx: @encode_ctxt, ebml_w: ebml::writer,
681681
ebml_w.end_tag();
682682
}
683683
encode_type(ecx, ebml_w, node_id_to_type(ecx.ccx.tcx, nitem.id));
684-
encode_symbol(ecx, ebml_w, nitem.id);
684+
if abi == native_abi_rust_builtin {
685+
astencode::encode_inlined_item(ecx, ebml_w, path,
686+
ii_native(nitem));
687+
} else {
688+
encode_symbol(ecx, ebml_w, nitem.id);
689+
}
685690
encode_path(ebml_w, path, ast_map::path_name(nitem.ident));
686691
}
687692
}

src/rustc/middle/ast_map.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ fn map_decoded_item(sess: session, map: map, path: path, ii: inlined_item) {
9191
// add it to the table now:
9292
alt ii {
9393
ii_item(i) { /* fallthrough */ }
94+
ii_native(i) {
95+
cx.map.insert(i.id, node_native_item(i, native_abi_rust_builtin,
96+
@path));
97+
}
9498
ii_method(impl_did, m) {
9599
map_method(impl_did, @path, m, cx);
96100
}

src/rustc/middle/lint.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,8 @@ fn check_ctypes(tcx: ty::ctxt, crate: @ast::crate) {
123123

124124
fn check_item(tcx: ty::ctxt, it: @ast::item) {
125125
alt it.node {
126-
ast::item_native_mod(nmod) {
126+
ast::item_native_mod(nmod) if attr::native_abi(it.attrs) !=
127+
either::right(ast::native_abi_rust_builtin) {
127128
for ni in nmod.items {
128129
alt ni.node {
129130
ast::native_item_fn(decl, tps) {

src/rustc/middle/trans/base.rs

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ fn trans_malloc_boxed_raw(bcx: block, t: ty::t,
337337
let llty = type_of(ccx, box_ptr);
338338

339339
// Get the tydesc for the body:
340-
let {bcx, val: lltydesc} = get_tydesc(bcx, t, static_ti);
340+
let lltydesc = get_tydesc(ccx, t, static_ti);
341341
lazily_emit_all_tydesc_glue(ccx, static_ti);
342342

343343
// Allocate space:
@@ -358,18 +358,18 @@ fn trans_malloc_boxed(bcx: block, t: ty::t) ->
358358

359359
// Type descriptor and type glue stuff
360360

361-
fn get_tydesc_simple(bcx: block, t: ty::t) -> result {
361+
fn get_tydesc_simple(ccx: @crate_ctxt, t: ty::t) -> ValueRef {
362362
let mut ti = none;
363-
get_tydesc(bcx, t, ti)
363+
get_tydesc(ccx, t, ti)
364364
}
365365

366-
fn get_tydesc(cx: block, t: ty::t,
367-
&static_ti: option<@tydesc_info>) -> result {
366+
fn get_tydesc(ccx: @crate_ctxt, t: ty::t,
367+
&static_ti: option<@tydesc_info>) -> ValueRef {
368368
assert !ty::type_has_params(t);
369369
// Otherwise, generate a tydesc if necessary, and return it.
370-
let info = get_static_tydesc(cx.ccx(), t);
370+
let info = get_static_tydesc(ccx, t);
371371
static_ti = some(info);
372-
ret rslt(cx, info.tydesc);
372+
info.tydesc
373373
}
374374

375375
fn get_static_tydesc(ccx: @crate_ctxt, t: ty::t) -> @tydesc_info {
@@ -699,7 +699,7 @@ fn get_res_dtor(ccx: @crate_ctxt, did: ast::def_id, substs: [ty::t])
699699
maybe_instantiate_inline(ccx, did)
700700
} else { did };
701701
assert did.crate == ast::local_crate;
702-
monomorphic_fn(ccx, did, substs, none).val
702+
monomorphic_fn(ccx, did, substs, none, none).val
703703
}
704704

705705
fn trans_res_drop(bcx: block, rs: ValueRef, did: ast::def_id,
@@ -1074,10 +1074,10 @@ fn call_tydesc_glue_full(cx: block, v: ValueRef, tydesc: ValueRef,
10741074
fn call_tydesc_glue(cx: block, v: ValueRef, t: ty::t, field: int) ->
10751075
block {
10761076
let _icx = cx.insn_ctxt("call_tydesc_glue");
1077-
let mut ti: option<@tydesc_info> = none;
1078-
let {bcx: bcx, val: td} = get_tydesc(cx, t, ti);
1079-
call_tydesc_glue_full(bcx, v, td, field, ti);
1080-
ret bcx;
1077+
let mut ti = none;
1078+
let td = get_tydesc(cx.ccx(), t, ti);
1079+
call_tydesc_glue_full(cx, v, td, field, ti);
1080+
ret cx;
10811081
}
10821082

10831083
fn call_cmp_glue(cx: block, lhs: ValueRef, rhs: ValueRef, t: ty::t,
@@ -1096,11 +1096,9 @@ fn call_cmp_glue(cx: block, lhs: ValueRef, rhs: ValueRef, t: ty::t,
10961096

10971097
let llrawlhsptr = BitCast(bcx, lllhs, T_ptr(T_i8()));
10981098
let llrawrhsptr = BitCast(bcx, llrhs, T_ptr(T_i8()));
1099-
let r = get_tydesc_simple(bcx, t);
1100-
let lltydesc = r.val;
1101-
let bcx = r.bcx;
1102-
let lltydescs = GEPi(bcx, lltydesc, [0, abi::tydesc_field_first_param]);
1103-
let lltydescs = Load(bcx, lltydescs);
1099+
let lltydesc = get_tydesc_simple(bcx.ccx(), t);
1100+
let lltydescs =
1101+
Load(bcx, GEPi(bcx, lltydesc, [0, abi::tydesc_field_first_param]));
11041102

11051103
let llfn = bcx.ccx().upcalls.cmp_type;
11061104

@@ -1171,9 +1169,7 @@ fn call_memmove(cx: block, dst: ValueRef, src: ValueRef,
11711169
session::arch_x86 | session::arch_arm { "llvm.memmove.p0i8.p0i8.i32" }
11721170
session::arch_x86_64 { "llvm.memmove.p0i8.p0i8.i64" }
11731171
};
1174-
let i = ccx.intrinsics;
1175-
assert (i.contains_key(key));
1176-
let memmove = i.get(key);
1172+
let memmove = ccx.intrinsics.get(key);
11771173
let src_ptr = PointerCast(cx, src, T_ptr(T_i8()));
11781174
let dst_ptr = PointerCast(cx, dst, T_ptr(T_i8()));
11791175
let size = IntCast(cx, n_bytes, ccx.int_type);
@@ -1911,7 +1907,8 @@ fn make_mono_id(ccx: @crate_ctxt, item: ast::def_id, substs: [ty::t],
19111907
}
19121908

19131909
fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, real_substs: [ty::t],
1914-
vtables: option<typeck::vtable_res>)
1910+
vtables: option<typeck::vtable_res>,
1911+
ref_id: option<ast::node_id>)
19151912
-> {val: ValueRef, must_cast: bool, intrinsic: bool} {
19161913
let _icx = ccx.insn_ctxt("monomorphic_fn");
19171914
let mut must_cast = false;
@@ -1952,6 +1949,8 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, real_substs: [ty::t],
19521949
}
19531950
ast_map::node_variant(v, _, pt) { (pt, v.node.name) }
19541951
ast_map::node_method(m, _, pt) { (pt, m.ident) }
1952+
ast_map::node_native_item(i, ast::native_abi_rust_builtin, pt)
1953+
{ (pt, i.ident) }
19551954
ast_map::node_native_item(_, abi, _) {
19561955
// Natives don't have to be monomorphized.
19571956
ret {val: get_item_val(ccx, fn_id.node),
@@ -1984,6 +1983,10 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, real_substs: [ty::t],
19841983
ast_map::node_item(@{node: ast::item_res(d, _, body, d_id, _), _}, _) {
19851984
trans_fn(ccx, pt, d, body, lldecl, no_self, psubsts, d_id, none);
19861985
}
1986+
ast_map::node_native_item(i, _, _) {
1987+
native::trans_builtin(ccx, lldecl, i, pt, option::get(psubsts),
1988+
ref_id);
1989+
}
19871990
ast_map::node_variant(v, enum_item, _) {
19881991
let tvs = ty::enum_variants(ccx.tcx, local_def(enum_item.id));
19891992
let this_tv = option::get(vec::find(*tvs, {|tv|
@@ -2036,6 +2039,10 @@ fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id)
20362039
trans_item(ccx, *item);
20372040
local_def(item.id)
20382041
}
2042+
csearch::found(ast::ii_native(item)) {
2043+
ccx.external.insert(fn_id, some(item.id));
2044+
local_def(item.id)
2045+
}
20392046
csearch::found_parent(parent_id, ast::ii_item(item)) {
20402047
ccx.external.insert(parent_id, some(item.id));
20412048
let mut my_id = 0;
@@ -2088,11 +2095,9 @@ fn lval_intrinsic_fn(bcx: block, val: ValueRef, tys: [ty::t],
20882095
let mut bcx = bcx;
20892096
let ccx = bcx.ccx();
20902097
let tds = vec::map(tys, {|t|
2091-
let mut ti = none;
2092-
let td_res = get_tydesc(bcx, t, ti);
2093-
bcx = td_res.bcx;
2098+
let mut ti = none, td = get_tydesc(bcx.ccx(), t, ti);
20942099
lazily_emit_all_tydesc_glue(ccx, ti);
2095-
td_res.val
2100+
td
20962101
});
20972102
let llfty = type_of_fn_from_ty(ccx, node_id_type(bcx, id));
20982103
let val = PointerCast(bcx, val, T_ptr(add_tydesc_params(
@@ -2124,7 +2129,7 @@ fn lval_static_fn_inner(bcx: block, fn_id: ast::def_id, id: ast::node_id,
21242129

21252130
if fn_id.crate == ast::local_crate && tys.len() > 0u {
21262131
let mut {val, must_cast, intrinsic} =
2127-
monomorphic_fn(ccx, fn_id, tys, vtables);
2132+
monomorphic_fn(ccx, fn_id, tys, vtables, some(id));
21282133
if intrinsic { ret lval_intrinsic_fn(bcx, val, tys, id); }
21292134
if must_cast {
21302135
val = PointerCast(bcx, val, T_ptr(type_of_fn_from_ty(
@@ -3318,7 +3323,7 @@ fn trans_log(lvl: @ast::expr, bcx: block, e: @ast::expr) -> block {
33183323
with_scope(bcx, "log") {|bcx|
33193324
let {bcx, val, _} = trans_temp_expr(bcx, e);
33203325
let e_ty = expr_ty(bcx, e);
3321-
let {bcx, val: tydesc} = get_tydesc_simple(bcx, e_ty);
3326+
let tydesc = get_tydesc_simple(ccx, e_ty);
33223327
// Call the polymorphic log function.
33233328
let {bcx, val} = spill_if_immediate(bcx, val, e_ty);
33243329
let val = PointerCast(bcx, val, T_ptr(T_i8()));

src/rustc/middle/trans/closure.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ fn allocate_cbox(bcx: block,
164164
box: ValueRef,
165165
&ti: option<@tydesc_info>) -> block {
166166
let bound_tydesc = GEPi(bcx, box, [0, abi::box_field_tydesc]);
167-
let {bcx, val: td} = base::get_tydesc(bcx, cdata_ty, ti);
167+
let td = base::get_tydesc(bcx.ccx(), cdata_ty, ti);
168168
Store(bcx, td, bound_tydesc);
169169
bcx
170170
}

src/rustc/middle/trans/common.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,10 @@ fn C_shape(ccx: @crate_ctxt, bytes: [u8]) -> ValueRef {
804804
ret llvm::LLVMConstPointerCast(llglobal, T_ptr(T_i8()));
805805
}
806806

807+
fn get_param(fndecl: ValueRef, param: uint) -> ValueRef {
808+
llvm::LLVMGetParam(fndecl, param as c_uint)
809+
}
810+
807811
// Used to identify cached monomorphized functions and vtables
808812
enum mono_param_id {
809813
mono_precise(ty::t, option<[mono_id]>),

src/rustc/middle/trans/impl.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ fn make_impl_vtable(ccx: @crate_ctxt, impl_id: ast::def_id, substs: [ty::t],
251251
} else {
252252
let m_id = method_with_name(ccx, impl_id, im.ident);
253253
if has_tps {
254-
monomorphic_fn(ccx, m_id, substs, some(vtables)).val
254+
monomorphic_fn(ccx, m_id, substs, some(vtables), none).val
255255
} else if m_id.crate == ast::local_crate {
256256
get_item_val(ccx, m_id.node)
257257
} else {

0 commit comments

Comments
 (0)