Skip to content

Commit bee55ad

Browse files
committed
---
yaml --- r: 14581 b: refs/heads/try c: def72bd h: refs/heads/master i: 14579: 7678dca v: v3
1 parent 647fa56 commit bee55ad

File tree

18 files changed

+600
-408
lines changed

18 files changed

+600
-408
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
refs/heads/master: 61b1875c16de39c166b0f4d54bba19f9c6777d1a
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 4a81779abd786ff22d71434c6d9a5917ea4cdfff
5-
refs/heads/try: 12c68bcd6df325cc369adce018c07dfe3e2b767a
5+
refs/heads/try: def72bda47977b3bc36143eba9692bff12a8303c
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105

branches/try/src/comp/metadata/astencode.rs

Lines changed: 127 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ import syntax::print::pprust;
3131

3232
export encode_inlined_item;
3333
export decode_inlined_item;
34+
export encode_inlined_method;
35+
export decode_inlined_method;
3436

3537
type decode_ctxt = @{
3638
cdata: cstore::crate_metadata,
@@ -49,49 +51,125 @@ iface tr {
4951
}
5052

5153
// ______________________________________________________________________
52-
// Enumerating the IDs which appear in an AST
54+
// Top-level methods.
55+
56+
// The type inline_fn should be a type that can represent both methods
57+
// and top-level items. As it happens, the type ast::method is perfect
58+
// for this purpose, but I use this typedef just to keep clear when
59+
// the thing may not, in fact, be an actual method in the AST but
60+
// rather some sort of function.
61+
enum inline_fn = @ast::method;
5362

5463
fn encode_inlined_item(ecx: @e::encode_ctxt,
5564
ebml_w: ebml::writer,
5665
path: ast_map::path,
5766
item: @ast::item) {
67+
let ifn = inline_fn(alt item.node {
68+
ast::item_fn(decl, tps, body) {
69+
@{ident: item.ident,
70+
attrs: item.attrs,
71+
tps: tps,
72+
decl: decl,
73+
body: body,
74+
id: item.id,
75+
span: item.span}
76+
}
77+
78+
_ {
79+
ecx.ccx.sess.span_bug(item.span, "Cannot inline non-function")
80+
}
81+
});
82+
83+
encode_inlined_fn(ecx, ebml_w, path, ifn);
84+
}
85+
86+
fn decode_inlined_item(cdata: cstore::crate_metadata,
87+
tcx: ty::ctxt,
88+
maps: maps,
89+
path: ast_map::path,
90+
par_doc: ebml::doc) -> option<@ast::item> {
91+
let oifn = decode_inlined_fn(cdata, tcx, maps, path, par_doc);
92+
option::map(oifn) {|ifn|
93+
let item = @{ident: ifn.ident,
94+
attrs: ifn.attrs,
95+
id: ifn.id,
96+
node: ast::item_fn(ifn.decl, ifn.tps, ifn.body),
97+
span: ifn.span};
98+
ast_map::map_decoded_item(tcx.items, path, item);
99+
item
100+
}
101+
}
102+
103+
fn encode_inlined_method(ecx: @e::encode_ctxt,
104+
ebml_w: ebml::writer,
105+
path: ast_map::path,
106+
mthd: @ast::method) {
107+
encode_inlined_fn(ecx, ebml_w, path, inline_fn(mthd))
108+
}
109+
110+
fn decode_inlined_method(cdata: cstore::crate_metadata,
111+
tcx: ty::ctxt,
112+
maps: maps,
113+
path: ast_map::path,
114+
par_doc: ebml::doc) -> option<@ast::method> {
115+
let oifn = decode_inlined_fn(cdata, tcx, maps, path, par_doc);
116+
option::map(oifn) {|ifn|
117+
ast_map::map_decoded_method(tcx.items, path, *ifn);
118+
*ifn
119+
}
120+
}
121+
122+
fn encode_inlined_fn(ecx: @e::encode_ctxt,
123+
ebml_w: ebml::writer,
124+
path: ast_map::path,
125+
ifn: inline_fn) {
126+
58127
#debug["> Encoding inlined item: %s::%s (%u)",
59128
ast_map::path_to_str(path),
60-
item.ident,
129+
ifn.ident,
61130
ebml_w.writer.tell()];
62-
let id_range = compute_id_range(item);
131+
132+
let id_range = compute_id_range(ifn);
63133
ebml_w.wr_tag(c::tag_ast as uint) {||
64134
encode_id_range(ebml_w, id_range);
65-
encode_ast(ebml_w, item);
66-
encode_side_tables_for_item(ecx, ebml_w, item);
135+
encode_ast(ebml_w, ifn);
136+
encode_side_tables_for_ifn(ecx, ebml_w, ifn);
67137
}
68-
#debug["< Encoded inlined item: %s (%u)",
138+
139+
#debug["< Encoded inlined fn: %s::%s (%u)",
69140
ast_map::path_to_str(path),
141+
ifn.ident,
70142
ebml_w.writer.tell()];
71143
}
72144

73-
fn decode_inlined_item(cdata: cstore::crate_metadata,
74-
tcx: ty::ctxt,
75-
maps: maps,
76-
path: ast_map::path,
77-
par_doc: ebml::doc) -> option<@ast::item> {
145+
// Decodes the inlined function and associated side tables. Does
146+
// *not* insert the function into the ast_map, since the correct way
147+
// to do this depends on whether this is an inlined item or method;
148+
// therefore, you ought to be invoking decode_inlined_item() or
149+
// decode_inlined_method() and not this helper function.
150+
fn decode_inlined_fn(cdata: cstore::crate_metadata,
151+
tcx: ty::ctxt,
152+
maps: maps,
153+
path: ast_map::path,
154+
par_doc: ebml::doc) -> option<inline_fn> {
78155
let dcx = @{cdata: cdata, tcx: tcx, maps: maps};
79156
alt par_doc.opt_child(c::tag_ast) {
80157
none { none }
81158
some(ast_doc) {
82-
#debug["> Decoding inlined item: %s", ast_map::path_to_str(path)];
159+
#debug["> Decoding inlined fn: %s", ast_map::path_to_str(path)];
83160
let from_id_range = decode_id_range(ast_doc);
84161
let to_id_range = reserve_id_range(dcx.tcx.sess, from_id_range);
85162
let xcx = @{dcx: dcx,
86163
from_id_range: from_id_range,
87164
to_id_range: to_id_range};
88-
let raw_item = decode_ast(ast_doc);
89-
let item = renumber_ast(xcx, raw_item);
90-
#debug[">> Item named: %s", item.ident];
91-
ast_map::map_decoded_item(dcx.tcx.items, path, item);
165+
let raw_ifn = decode_ast(ast_doc);
166+
let ifn = renumber_ast(xcx, raw_ifn);
167+
#debug["Fn named: %s", ifn.ident];
92168
decode_side_tables(xcx, ast_doc);
93-
#debug["< Decoded inlined item: %s", ast_map::path_to_str(path)];
94-
some(item)
169+
#debug["< Decoded inlined fn: %s::%s",
170+
ast_map::path_to_str(path),
171+
ifn.ident];
172+
some(ifn)
95173
}
96174
}
97175
}
@@ -105,7 +183,7 @@ fn empty(range: id_range) -> bool {
105183
range.min >= range.max
106184
}
107185

108-
fn visit_ids(item: @ast::item, vfn: fn@(ast::node_id)) {
186+
fn visit_ids(ifn: inline_fn, vfn: fn@(ast::node_id)) {
109187
let visitor = visit::mk_simple_visitor(@{
110188
visit_mod: fn@(_m: ast::_mod, _sp: span, id: ast::node_id) {
111189
vfn(id)
@@ -214,13 +292,13 @@ fn visit_ids(item: @ast::item, vfn: fn@(ast::node_id)) {
214292
}
215293
});
216294

217-
visitor.visit_item(item, (), visitor);
295+
visit::visit_method_helper(*ifn, (), visitor);
218296
}
219297

220-
fn compute_id_range(item: @ast::item) -> id_range {
298+
fn compute_id_range(ifn: inline_fn) -> id_range {
221299
let min = @mutable int::max_value;
222300
let max = @mutable int::min_value;
223-
visit_ids(item) {|id|
301+
visit_ids(ifn) {|id|
224302
*min = int::min(*min, id);
225303
*max = int::max(*max, id + 1);
226304
}
@@ -317,25 +395,25 @@ impl deserializer_helpers<D: serialization::deserializer> for D {
317395
// We also have to adjust the spans: for now we just insert a dummy span,
318396
// but eventually we should add entries to the local codemap as required.
319397

320-
fn encode_ast(ebml_w: ebml::writer, item: @ast::item) {
398+
fn encode_ast(ebml_w: ebml::writer, ifn: inline_fn) {
321399
ebml_w.wr_tag(c::tag_tree as uint) {||
322-
astencode_gen::serialize_syntax_ast_item(ebml_w, *item);
400+
astencode_gen::serialize_syntax_ast_method(ebml_w, **ifn)
323401
}
324402
}
325403

326-
fn decode_ast(par_doc: ebml::doc) -> @ast::item {
404+
fn decode_ast(par_doc: ebml::doc) -> inline_fn {
327405
let chi_doc = par_doc[c::tag_tree];
328406
let d = serialization::mk_ebml_deserializer(chi_doc);
329-
@astencode_gen::deserialize_syntax_ast_item(d)
407+
inline_fn(@astencode_gen::deserialize_syntax_ast_method(d))
330408
}
331409

332-
fn renumber_ast(xcx: extended_decode_ctxt, item: @ast::item) -> @ast::item {
410+
fn renumber_ast(xcx: extended_decode_ctxt, ifn: inline_fn) -> inline_fn {
333411
let fld = fold::make_fold({
334412
new_id: xcx.tr_id(_),
335413
new_span: xcx.tr_span(_)
336414
with *fold::default_ast_fold()
337415
});
338-
fld.fold_item(item)
416+
inline_fn(fld.fold_method(*ifn))
339417
}
340418

341419
// ______________________________________________________________________
@@ -586,11 +664,11 @@ impl writer for ebml::writer {
586664
}
587665
}
588666

589-
fn encode_side_tables_for_item(ecx: @e::encode_ctxt,
590-
ebml_w: ebml::writer,
591-
item: @ast::item) {
667+
fn encode_side_tables_for_ifn(ecx: @e::encode_ctxt,
668+
ebml_w: ebml::writer,
669+
ifn: inline_fn) {
592670
ebml_w.wr_tag(c::tag_table as uint) {||
593-
visit_ids(item, fn@(id: ast::node_id) {
671+
visit_ids(ifn, fn@(id: ast::node_id) {
594672
// Note: this will cause a copy of ebml_w, which is bad as
595673
// it has mutable fields. But I believe it's harmless since
596674
// we generate balanced EBML.
@@ -820,7 +898,21 @@ fn decode_side_tables(xcx: extended_decode_ctxt,
820898
}
821899

822900
// ______________________________________________________________________
823-
// Testing
901+
// Testing of astencode_gen
902+
903+
#[cfg(test)]
904+
fn encode_item_ast(ebml_w: ebml::writer, item: @ast::item) {
905+
ebml_w.wr_tag(c::tag_tree as uint) {||
906+
astencode_gen::serialize_syntax_ast_item(ebml_w, *item);
907+
}
908+
}
909+
910+
#[cfg(test)]
911+
fn decode_item_ast(par_doc: ebml::doc) -> @ast::item {
912+
let chi_doc = par_doc[c::tag_tree];
913+
let d = serialization::mk_ebml_deserializer(chi_doc);
914+
@astencode_gen::deserialize_syntax_ast_item(d)
915+
}
824916

825917
#[cfg(test)]
826918
fn new_parse_sess() -> parser::parse_sess {
@@ -864,9 +956,9 @@ fn roundtrip(in_item: @ast::item) {
864956
#debug["in_item = %s", pprust::item_to_str(in_item)];
865957
let mbuf = io::mk_mem_buffer();
866958
let ebml_w = ebml::mk_writer(io::mem_buffer_writer(mbuf));
867-
encode_ast(ebml_w, in_item);
959+
encode_item_ast(ebml_w, in_item);
868960
let ebml_doc = ebml::new_doc(@io::mem_buffer_buf(mbuf));
869-
let out_item = decode_ast(ebml_doc);
961+
let out_item = decode_item_ast(ebml_doc);
870962
#debug["out_item = %s", pprust::item_to_str(out_item)];
871963
assert in_item == out_item;
872964
}

branches/try/src/comp/metadata/astencode_gen.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8748,3 +8748,12 @@ fn deserialize_syntax_ast_def_id<S: std::serialization::deserializer>(s: S) ->
87488748
syntax::ast::def_id {
87498749
deserialize_162(s)
87508750
}
8751+
fn serialize_syntax_ast_method<S: std::serialization::serializer>(s: S,
8752+
v:
8753+
syntax::ast::method) {
8754+
serialize_160(s, v);
8755+
}
8756+
fn deserialize_syntax_ast_method<S: std::serialization::deserializer>(s: S) ->
8757+
syntax::ast::method {
8758+
deserialize_160(s)
8759+
}

branches/try/src/comp/middle/ast_map.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,15 @@ fn map_decoded_item(map: map, path: path, i: @item) {
7373
v.visit_item(i, cx, v);
7474
}
7575

76+
fn map_decoded_method(map: map, path: path, m: @method) {
77+
// As above.
78+
let cx = {map: map,
79+
mutable path: path,
80+
mutable local_id: 0u};
81+
let v = mk_ast_map_visitor();
82+
visit::visit_method_helper(m, cx, v);
83+
}
84+
7685
fn map_fn(fk: visit::fn_kind, decl: fn_decl, body: blk,
7786
sp: codemap::span, id: node_id, cx: ctx, v: vt) {
7887
for a in decl.inputs {

branches/try/src/comp/syntax/visit.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,7 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) {
130130
alt ifce { some(ty) { v.visit_ty(ty, e, v); } _ {} }
131131
v.visit_ty(ty, e, v);
132132
for m in methods {
133-
v.visit_fn(fk_method(m.ident, m.tps), m.decl, m.body, m.span,
134-
m.id, e, v);
133+
visit_method_helper(m, e, v)
135134
}
136135
}
137136
item_class(tps, members, _, ctor_decl, ctor_blk) {
@@ -252,6 +251,15 @@ fn visit_fn_decl<E>(fd: fn_decl, e: E, v: vt<E>) {
252251
v.visit_ty(fd.output, e, v);
253252
}
254253

254+
// Note: there is no visit_method() method in the visitor, instead override
255+
// visit_fn() and check for fk_method(). I named this visit_method_helper()
256+
// because it is not a default impl of any method, though I doubt that really
257+
// clarifies anything. - Niko
258+
fn visit_method_helper<E>(m: @method, e: E, v: vt<E>) {
259+
v.visit_fn(fk_method(m.ident, m.tps), m.decl, m.body, m.span,
260+
m.id, e, v);
261+
}
262+
255263
fn visit_fn<E>(fk: fn_kind, decl: fn_decl, body: blk, _sp: span,
256264
_id: node_id, e: E, v: vt<E>) {
257265
visit_fn_decl(decl, e, v);

branches/try/src/compiletest/runtest.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -289,10 +289,15 @@ fn compile_test(config: config, props: test_props,
289289
testfile: str) -> procres {
290290
vec::iter(props.aux_builds) {|rel_ab|
291291
let abs_ab = fs::connect(config.aux_base, rel_ab);
292-
compose_and_run(config, abs_ab,
293-
make_compile_args(_, props, ["--lib"],
294-
make_lib_name, _),
295-
config.compile_lib_path, option::none);
292+
let auxres = compose_and_run(config, abs_ab,
293+
make_compile_args(_, props, ["--lib"],
294+
make_lib_name, _),
295+
config.compile_lib_path, option::none);
296+
if auxres.status != 0 {
297+
fatal_procres(
298+
#fmt["auxiliary build of %s failed to compile: ", abs_ab],
299+
auxres);
300+
}
296301
}
297302

298303
compose_and_run(config, testfile,

branches/try/src/etc/gen-astencode

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ function msg {
1616

1717
M=src/comp/metadata
1818
GEN_TYPES="syntax::ast::item syntax::ast::def middle::typeck::method_origin \
19-
middle::freevars::freevar_entry syntax::ast::def_id"
19+
middle::freevars::freevar_entry syntax::ast::def_id
20+
syntax::ast::method"
2021

2122
# Find serializer tool:
2223
for S in build/*/stage1/bin/serializer; do

branches/try/src/libcore/sys.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,15 @@ native mod rustrt {
2020
fn unsupervise();
2121
fn shape_log_str<T>(t: *sys::type_desc, data: T) -> str;
2222
fn rust_set_exit_status(code: ctypes::intptr_t);
23-
fn rust_frame_address() -> ctypes::uintptr_t;
2423
}
2524

2625
#[abi = "rust-intrinsic"]
2726
native mod rusti {
2827
fn get_type_desc<T>() -> *type_desc;
28+
29+
// Invokes __builtin_frame_address().
30+
// See <http://gcc.gnu.org/onlinedocs/gcc/Return-Address.html>.
31+
fn frame_address(n: ctypes::c_uint) -> ctypes::uintptr_t;
2932
}
3033

3134
/*
@@ -78,10 +81,6 @@ fn log_str<T>(t: T) -> str {
7881
rustrt::shape_log_str(get_type_desc::<T>(), t)
7982
}
8083

81-
fn frame_address() -> uint {
82-
rustrt::rust_frame_address()
83-
}
84-
8584
#[doc(
8685
brief = "Sets the process exit code",
8786
desc = "Sets the exit code returned by the process if all supervised \

branches/try/src/rt/intrinsics/intrinsics.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,3 +166,9 @@ upcall_vec_push(rust_vec** vp,
166166
type_desc* elt_ty, void* elt) {
167167
upcall_intrinsic_vec_push(vp, elt_ty, elt);
168168
}
169+
170+
extern "C" CDECL void
171+
rust_intrinsic_frame_address(void **p, unsigned n) {
172+
*p = __builtin_frame_address(n);
173+
}
174+

0 commit comments

Comments
 (0)