Skip to content

Commit de82a9b

Browse files
author
Elliott Slaughter
committed
Move fail upcall into rust libcore.
1 parent 019a41b commit de82a9b

File tree

10 files changed

+147
-19
lines changed

10 files changed

+147
-19
lines changed

src/libcore/core.rc

+7
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ export either, option, result, iter;
4141
export libc, os, io, run, rand, sys, unsafe, logging;
4242
export arc, comm, task, future, pipes;
4343
export extfmt;
44+
// The test harness links against core, so don't include runtime in tests.
45+
// FIXME (#2861): Uncomment this after snapshot gets updated.
46+
//#[cfg(notest)]
47+
export rt;
4448
export tuple;
4549
export to_str, to_bytes;
4650
export dvec, dvec_iter;
@@ -206,6 +210,9 @@ mod unsafe;
206210
// Exported but not part of the public interface
207211

208212
mod extfmt;
213+
// The test harness links against core, so don't include runtime in tests.
214+
#[cfg(notest)]
215+
mod rt;
209216

210217

211218
// For internal use, not exported

src/libcore/rt.rs

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//! Runtime calls emitted by the compiler.
2+
3+
import libc::c_char;
4+
import libc::size_t;
5+
6+
type rust_task = libc::c_void;
7+
8+
extern mod rustrt {
9+
#[rust_stack]
10+
fn rust_upcall_fail(expr: *c_char, file: *c_char, line: size_t);
11+
}
12+
13+
// FIXME (#2861): This needs both the attribute, and the name prefixed with
14+
// 'rt_', otherwise the compiler won't find it. To fix this, see
15+
// gather_rust_rtcalls.
16+
#[rt(fail)]
17+
fn rt_fail(expr: *c_char, file: *c_char, line: size_t) {
18+
rustrt::rust_upcall_fail(expr, file, line);
19+
}
20+
21+
// Local Variables:
22+
// mode: rust;
23+
// fill-column: 78;
24+
// indent-tabs-mode: nil
25+
// c-basic-offset: 4
26+
// buffer-file-coding-system: utf-8-unix
27+
// End:

src/rt/rust_upcall.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,16 @@ upcall_fail(char const *expr,
9898
UPCALL_SWITCH_STACK(task, &args, upcall_s_fail);
9999
}
100100

101+
// FIXME (#2861): Alias used by libcore/rt.rs to avoid naming conflicts with
102+
// autogenerated wrappers for upcall_fail. Remove this when we fully move away
103+
// away from the C upcall path.
104+
extern "C" CDECL void
105+
rust_upcall_fail(char const *expr,
106+
char const *file,
107+
size_t line) {
108+
upcall_fail(expr, file, line);
109+
}
110+
101111
struct s_trace_args {
102112
rust_task *task;
103113
char const *msg;

src/rustc/driver/driver.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,11 @@ fn build_configuration(sess: session, argv0: ~str, input: input) ->
6969
// If the user wants a test runner, then add the test cfg
7070
let gen_cfg =
7171
{
72-
if sess.opts.test && !attr::contains_name(user_cfg, ~"test")
73-
{
72+
if sess.opts.test && !attr::contains_name(user_cfg, ~"test") {
7473
~[attr::mk_word_item(@~"test")]
75-
} else { ~[] }
74+
} else {
75+
~[attr::mk_word_item(@~"notest")]
76+
}
7677
};
7778
ret vec::append(vec::append(user_cfg, gen_cfg), default_cfg);
7879
}

src/rustc/middle/trans/base.rs

+92-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import link::{mangle_internal_name_by_type_only,
3737
mangle_internal_name_by_path,
3838
mangle_internal_name_by_path_and_seq,
3939
mangle_exported_name};
40-
import metadata::{csearch, cstore, encoder};
40+
import metadata::{csearch, cstore, decoder, encoder};
4141
import metadata::common::link_meta;
4242
import util::ppaux;
4343
import util::ppaux::{ty_to_str, ty_to_short_str};
@@ -3942,11 +3942,25 @@ fn trans_fail_value(bcx: block, sp_opt: option<span>,
39423942
let V_str = PointerCast(bcx, V_fail_str, T_ptr(T_i8()));
39433943
let V_filename = PointerCast(bcx, V_filename, T_ptr(T_i8()));
39443944
let args = ~[V_str, V_filename, C_int(ccx, V_line)];
3945-
let bcx = invoke(bcx, bcx.ccx().upcalls._fail, args);
3945+
let bcx = trans_rtcall(bcx, ~"fail", args);
39463946
Unreachable(bcx);
39473947
ret bcx;
39483948
}
39493949

3950+
fn trans_rtcall(bcx: block, name: ~str, args: ~[ValueRef]) -> block {
3951+
let did = bcx.ccx().rtcalls[name];
3952+
let fty = if did.crate == ast::local_crate {
3953+
ty::node_id_to_type(bcx.ccx().tcx, did.node)
3954+
} else {
3955+
csearch::get_type(bcx.ccx().tcx, did).ty
3956+
};
3957+
let rty = ty::ty_fn_ret(fty);
3958+
ret trans_call_inner(
3959+
bcx, none, fty, rty,
3960+
|bcx| lval_static_fn_inner(bcx, did, 0, ~[], none),
3961+
arg_vals(args), ignore);
3962+
}
3963+
39503964
fn trans_break_cont(bcx: block, to_end: bool)
39513965
-> block {
39523966
let _icx = bcx.insn_ctxt(~"trans_break_cont");
@@ -5314,6 +5328,79 @@ fn trap(bcx: block) {
53145328
}
53155329
}
53165330

5331+
fn push_rtcall(ccx: @crate_ctxt, name: ~str, did: ast::def_id) {
5332+
if ccx.rtcalls.contains_key(name) {
5333+
fail #fmt("multiple definitions for runtime call %s", name);
5334+
}
5335+
ccx.rtcalls.insert(name, did);
5336+
}
5337+
5338+
fn gather_local_rtcalls(ccx: @crate_ctxt, crate: @ast::crate) {
5339+
visit::visit_crate(*crate, (), visit::mk_simple_visitor(@{
5340+
visit_item: |item| alt item.node {
5341+
ast::item_fn(decl, _, _) {
5342+
let attr_metas = attr::attr_metas(
5343+
attr::find_attrs_by_name(item.attrs, ~"rt"));
5344+
do vec::iter(attr_metas) |attr_meta| {
5345+
alt attr::get_meta_item_list(attr_meta) {
5346+
some(list) {
5347+
let name = *attr::get_meta_item_name(vec::head(list));
5348+
push_rtcall(ccx, name, {crate: ast::local_crate,
5349+
node: item.id});
5350+
}
5351+
none {}
5352+
}
5353+
}
5354+
}
5355+
_ {}
5356+
}
5357+
with *visit::default_simple_visitor()
5358+
}));
5359+
}
5360+
5361+
fn gather_external_rtcalls(ccx: @crate_ctxt) {
5362+
do cstore::iter_crate_data(ccx.sess.cstore) |_cnum, cmeta| {
5363+
do decoder::each_path(cmeta) |path| {
5364+
let pathname = path.path_string;
5365+
alt path.def_like {
5366+
decoder::dl_def(d) {
5367+
alt d {
5368+
ast::def_fn(did, _) {
5369+
// FIXME (#2861): This should really iterate attributes
5370+
// like gather_local_rtcalls, but we'll need to
5371+
// export attributes in metadata/encoder before we can do
5372+
// that.
5373+
let sentinel = "rt::rt_";
5374+
let slen = str::len(sentinel);
5375+
if str::starts_with(pathname, sentinel) {
5376+
let name = str::substr(pathname,
5377+
slen, str::len(pathname)-slen);
5378+
push_rtcall(ccx, name, did);
5379+
}
5380+
}
5381+
_ {}
5382+
}
5383+
}
5384+
_ {}
5385+
}
5386+
true
5387+
}
5388+
}
5389+
}
5390+
5391+
fn gather_rtcalls(ccx: @crate_ctxt, crate: @ast::crate) {
5392+
gather_local_rtcalls(ccx, crate);
5393+
gather_external_rtcalls(ccx);
5394+
5395+
// FIXME (#2861): Check for other rtcalls too, once they are
5396+
// supported. Also probably want to check type signature so we don't crash
5397+
// in some obscure place in LLVM if the user provides the wrong signature
5398+
// for an rtcall.
5399+
if !ccx.rtcalls.contains_key(~"fail") {
5400+
fail ~"no definition for runtime call fail";
5401+
}
5402+
}
5403+
53175404
fn create_module_map(ccx: @crate_ctxt) -> ValueRef {
53185405
let elttype = T_struct(~[ccx.int_type, ccx.int_type]);
53195406
let maptype = T_array(elttype, ccx.module_data.size() + 1u);
@@ -5544,6 +5631,7 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
55445631
upcalls:
55455632
upcall::declare_upcalls(targ_cfg, tn, tydesc_type,
55465633
llmod),
5634+
rtcalls: str_hash::<ast::def_id>(),
55475635
tydesc_type: tydesc_type,
55485636
int_type: int_type,
55495637
float_type: float_type,
@@ -5557,6 +5645,8 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
55575645
mut do_not_commit_warning_issued: false};
55585646

55595647

5648+
gather_rtcalls(ccx, crate);
5649+
55605650
{
55615651
let _icx = ccx.insn_ctxt(~"data");
55625652
trans_constants(ccx, crate);

src/rustc/middle/trans/common.rs

+1
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ type crate_ctxt = {
118118
maps: astencode::maps,
119119
stats: stats,
120120
upcalls: @upcall::upcalls,
121+
rtcalls: hashmap<~str, ast::def_id>,
121122
tydesc_type: TypeRef,
122123
int_type: TypeRef,
123124
float_type: TypeRef,

src/test/run-pass/module-polymorphism.rc

+3-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
#[no_core];
2-
3-
41
#[path = "module-polymorphism-files"]
5-
mod float {
2+
mod my_float {
63

74
// The type of the float
85
import inst::T;
@@ -18,7 +15,7 @@ mod float {
1815
}
1916

2017
#[path = "module-polymorphism-files"]
21-
mod f64 {
18+
mod my_f64 {
2219

2320
import inst::T;
2421

@@ -33,7 +30,7 @@ mod f64 {
3330
}
3431

3532
#[path = "module-polymorphism-files"]
36-
mod f32 {
33+
mod my_f32 {
3734
import inst::T;
3835

3936
#[path = "inst_f32.rs"]

src/test/run-pass/module-polymorphism.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
fn main() {
66
// All of these functions are defined by a single module
77
// source file but instantiated for different types
8-
assert float::template::plus(1.0f, 2.0f) == 3.0f;
9-
assert f64::template::plus(1.0f64, 2.0f64) == 3.0f64;
10-
assert f32::template::plus(1.0f32, 2.0f32) == 3.0f32;
8+
assert my_float::template::plus(1.0f, 2.0f) == 3.0f;
9+
assert my_f64::template::plus(1.0f64, 2.0f64) == 3.0f64;
10+
assert my_f32::template::plus(1.0f32, 2.0f32) == 3.0f32;
1111
}

src/test/run-pass/module-polymorphism2.rc

-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
#[no_core];
2-
3-
41
#[path = "module-polymorphism2-files"]
52
mod mystd {
63

src/test/run-pass/module-polymorphism3.rc

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#[no_core];
2-
31
// Use one template module to specify in a single file the implementation
42
// of functions for multiple types
53

0 commit comments

Comments
 (0)