Skip to content

Commit c4bcd0a

Browse files
msullivanbrson
authored andcommitted
Move collect_upvars into its own file.
1 parent 2e6197a commit c4bcd0a

File tree

3 files changed

+96
-72
lines changed

3 files changed

+96
-72
lines changed

src/comp/middle/freevars.rs

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// A pass that annotates for each loops with the free variables that
2+
// they contain.
3+
4+
import std::map;
5+
import std::map::*;
6+
import syntax::ast;
7+
import syntax::walk;
8+
import driver::session;
9+
import middle::ty;
10+
import syntax::codemap::span;
11+
12+
13+
14+
// Searches through part of the AST for all references to locals or
15+
// upvars in this frame and returns the list of definition IDs thus found.
16+
// Since we want to be able to collect upvars in some arbitrary piece
17+
// of the AST, we take a walker function that we invoke with a visitor
18+
// in order to start the search.
19+
fn collect_upvars(&ty::ctxt tcx, &fn (&walk::ast_visitor) walker,
20+
ast::node_id[] initial_decls) -> ast::node_id[] {
21+
type env =
22+
@rec(mutable ast::node_id[] refs,
23+
hashmap[ast::node_id, ()] decls,
24+
resolve::def_map def_map,
25+
session::session sess);
26+
27+
fn walk_fn(env e, &ast::_fn f, &ast::ty_param[] tps, &span sp,
28+
&ast::fn_ident i, ast::node_id nid) {
29+
for (ast::arg a in f.decl.inputs) { e.decls.insert(a.id, ()); }
30+
}
31+
fn walk_expr(env e, &@ast::expr expr) {
32+
alt (expr.node) {
33+
case (ast::expr_path(?path)) {
34+
if (! e.def_map.contains_key(expr.id)) {
35+
e.sess.span_fatal(expr.span,
36+
"internal error in collect_upvars");
37+
}
38+
alt (e.def_map.get(expr.id)) {
39+
case (ast::def_arg(?did)) { e.refs += ~[did._1]; }
40+
case (ast::def_local(?did)) { e.refs += ~[did._1]; }
41+
case (ast::def_binding(?did)) { e.refs += ~[did._1]; }
42+
case (_) { /* no-op */ }
43+
}
44+
}
45+
case (_) { }
46+
}
47+
}
48+
fn walk_local(env e, &@ast::local local) {
49+
e.decls.insert(local.node.id, ());
50+
}
51+
fn walk_pat(env e, &@ast::pat p) {
52+
alt (p.node) {
53+
case (ast::pat_bind(_)) {
54+
e.decls.insert(p.id, ());
55+
}
56+
case (_) {}
57+
}
58+
}
59+
let hashmap[ast::node_id, ()] decls = new_int_hash[()]();
60+
for (ast::node_id decl in initial_decls) { decls.insert(decl, ()); }
61+
62+
let env e =
63+
@rec(mutable refs=~[],
64+
decls=decls,
65+
def_map=tcx.def_map,
66+
sess=tcx.sess);
67+
auto visitor =
68+
@rec(visit_fn_pre=bind walk_fn(e, _, _, _, _, _),
69+
visit_local_pre=bind walk_local(e, _),
70+
visit_expr_pre=bind walk_expr(e, _),
71+
visit_pat_pre=bind walk_pat(e, _)
72+
with walk::default_visitor());
73+
walker(*visitor);
74+
// Calculate (refs - decls). This is the set of captured upvars.
75+
76+
let ast::node_id[] result = ~[];
77+
for (ast::node_id ref_id_ in e.refs) {
78+
auto ref_id = ref_id_;
79+
if (!decls.contains_key(ref_id)) { result += ~[ref_id]; }
80+
}
81+
ret result;
82+
}
83+
84+
// Local Variables:
85+
// mode: rust
86+
// fill-column: 78;
87+
// indent-tabs-mode: nil
88+
// c-basic-offset: 4
89+
// buffer-file-coding-system: utf-8-unix
90+
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
91+
// End:

src/comp/middle/trans.rs

+4-72
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import syntax::ast;
2727
import syntax::walk;
2828
import driver::session;
2929
import middle::ty;
30+
import middle::freevars;
3031
import back::link;
3132
import back::x86;
3233
import back::abi;
@@ -4107,76 +4108,6 @@ fn trans_for(&@block_ctxt cx, &@ast::local local, &@ast::expr seq,
41074108

41084109
// Iterator translation
41094110

4110-
// Searches through part of the AST for all references to locals or
4111-
// upvars in this frame and returns the list of definition IDs thus found.
4112-
// Since we want to be able to collect upvars in some arbitrary piece
4113-
// of the AST, we take a walker function that we invoke with a visitor
4114-
// in order to start the search.
4115-
fn collect_upvars(&@block_ctxt cx, &fn (&walk::ast_visitor) walker,
4116-
ast::node_id[] initial_decls) -> ast::node_id[] {
4117-
type env =
4118-
@rec(mutable ast::node_id[] refs,
4119-
hashmap[ast::node_id, ()] decls,
4120-
resolve::def_map def_map,
4121-
session::session sess);
4122-
4123-
fn walk_fn(env e, &ast::_fn f, &ast::ty_param[] tps, &span sp,
4124-
&ast::fn_ident i, ast::node_id nid) {
4125-
for (ast::arg a in f.decl.inputs) { e.decls.insert(a.id, ()); }
4126-
}
4127-
fn walk_expr(env e, &@ast::expr expr) {
4128-
alt (expr.node) {
4129-
case (ast::expr_path(?path)) {
4130-
if (! e.def_map.contains_key(expr.id)) {
4131-
e.sess.span_fatal(expr.span,
4132-
"internal error in collect_upvars");
4133-
}
4134-
alt (e.def_map.get(expr.id)) {
4135-
case (ast::def_arg(?did)) { e.refs += ~[did._1]; }
4136-
case (ast::def_local(?did)) { e.refs += ~[did._1]; }
4137-
case (ast::def_binding(?did)) { e.refs += ~[did._1]; }
4138-
case (_) { /* no-op */ }
4139-
}
4140-
}
4141-
case (_) { }
4142-
}
4143-
}
4144-
fn walk_local(env e, &@ast::local local) {
4145-
e.decls.insert(local.node.id, ());
4146-
}
4147-
fn walk_pat(env e, &@ast::pat p) {
4148-
alt (p.node) {
4149-
case (ast::pat_bind(_)) {
4150-
e.decls.insert(p.id, ());
4151-
}
4152-
case (_) {}
4153-
}
4154-
}
4155-
let hashmap[ast::node_id, ()] decls = new_int_hash[()]();
4156-
for (ast::node_id decl in initial_decls) { decls.insert(decl, ()); }
4157-
4158-
let env e =
4159-
@rec(mutable refs=~[],
4160-
decls=decls,
4161-
def_map=cx.fcx.lcx.ccx.tcx.def_map,
4162-
sess=cx.fcx.lcx.ccx.tcx.sess);
4163-
auto visitor =
4164-
@rec(visit_fn_pre=bind walk_fn(e, _, _, _, _, _),
4165-
visit_local_pre=bind walk_local(e, _),
4166-
visit_expr_pre=bind walk_expr(e, _),
4167-
visit_pat_pre=bind walk_pat(e, _)
4168-
with walk::default_visitor());
4169-
walker(*visitor);
4170-
// Calculate (refs - decls). This is the set of captured upvars.
4171-
4172-
let ast::node_id[] result = ~[];
4173-
for (ast::node_id ref_id_ in e.refs) {
4174-
auto ref_id = ref_id_;
4175-
if (!decls.contains_key(ref_id)) { result += ~[ref_id]; }
4176-
}
4177-
ret result;
4178-
}
4179-
41804111
// Finds the ValueRef associated with a variable in a function
41814112
// context. It checks locals, upvars, and args.
41824113
fn find_variable(&@fn_ctxt fcx, ast::node_id nid) -> ValueRef {
@@ -4353,8 +4284,9 @@ fn trans_for_each(&@block_ctxt cx, &@ast::local local, &@ast::expr seq,
43534284
// FIXME: possibly support alias-mode here?
43544285
auto decl_ty = node_id_type(lcx.ccx, local.node.id);
43554286
auto decl_id = local.node.id;
4356-
auto upvars = collect_upvars(cx, bind walk::walk_block(_, body),
4357-
~[decl_id]);
4287+
auto upvars = freevars::collect_upvars(cx.fcx.lcx.ccx.tcx,
4288+
bind walk::walk_block(_, body),
4289+
~[decl_id]);
43584290

43594291
auto environment_data = build_environment(cx, upvars);
43604292
auto llenvptr = environment_data._0;

src/comp/rustc.rc

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ mod middle {
2626
mod resolve;
2727
mod typeck;
2828
mod alias;
29+
mod freevars;
2930

3031
mod tstate {
3132
mod ck;

0 commit comments

Comments
 (0)