Move hash table iteration over to block-taking functions

Issue #1056
This commit is contained in:
Marijn Haverbeke 2011-10-21 12:21:27 +02:00
parent 9bb4595c53
commit 4ebbbe597e
9 changed files with 82 additions and 86 deletions

View File

@ -72,12 +72,8 @@ fn have_crate_data(cstore: cstore, cnum: ast::crate_num) -> bool {
ret p(cstore).metas.contains_key(cnum);
}
iter iter_crate_data(cstore: cstore) ->
@{key: ast::crate_num, val: crate_metadata} {
for each kv: @{key: ast::crate_num, val: crate_metadata} in
p(cstore).metas.items() {
put kv;
}
fn iter_crate_data(cstore: cstore, i: block(ast::crate_num, crate_metadata)) {
p(cstore).metas.items {|k,v| i(k, v);};
}
fn add_used_crate_file(cstore: cstore, lib: str) {

View File

@ -371,20 +371,19 @@ fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml::writer) ->
[entry<int>] {
let index: [entry<int>] = [];
ebml::start_tag(ebml_w, tag_items_data);
for each kvp: @{key: node_id, val: middle::ast_map::ast_node} in
ecx.ccx.ast_map.items() {
alt kvp.val {
ecx.ccx.ast_map.items {|key, val|
alt val {
middle::ast_map::node_item(i) {
index += [{val: kvp.key, pos: ebml_w.writer.tell()}];
index += [{val: key, pos: ebml_w.writer.tell()}];
encode_info_for_item(ecx, ebml_w, i, index);
}
middle::ast_map::node_native_item(i) {
index += [{val: kvp.key, pos: ebml_w.writer.tell()}];
index += [{val: key, pos: ebml_w.writer.tell()}];
encode_info_for_native_item(ecx, ebml_w, i);
}
_ { }
}
}
};
ebml::end_tag(ebml_w);
ret index;
}
@ -544,9 +543,9 @@ fn encode_crate_deps(ebml_w: ebml::writer, cstore: cstore::cstore) {
// Pull the cnums and names out of cstore
let pairs: [mutable numname] = [mutable];
for each hashkv: hashkv in cstore::iter_crate_data(cstore) {
pairs += [mutable {crate: hashkv.key, ident: hashkv.val.name}];
}
cstore::iter_crate_data(cstore) {|key, val|
pairs += [mutable {crate: key, ident: val.name}];
};
// Sort by cnum
fn lteq(kv1: numname, kv2: numname) -> bool { kv1.crate <= kv2.crate }

View File

@ -86,14 +86,13 @@ fn new_smallintmap_int_adapter<@V>() -> std::map::hashmap<int, V> {
// the entire codebase adapting all the callsites to the different
// interface.
// FIXME: hashmap and smallintmap should support the same interface.
fn new_smallintmap_adapter<@K,
@V>(key_idx: fn(K) -> uint, idx_key: fn(uint) -> K)
-> std::map::hashmap<K, V> {
fn new_smallintmap_adapter<@K, @V>(key_idx: fn(K) -> uint,
idx_key: fn(uint) -> K)
-> std::map::hashmap<K, V> {
obj adapter<@K,
@V>(map: smallintmap::smallintmap<V>,
key_idx: fn(K) -> uint,
idx_key: fn(uint) -> K) {
obj adapter<@K, @V>(map: smallintmap::smallintmap<V>,
key_idx: fn(K) -> uint,
idx_key: fn(uint) -> K) {
fn size() -> uint { fail }
@ -117,22 +116,29 @@ fn new_smallintmap_adapter<@K,
fn rehash() { fail }
iter items() -> @{key: K, val: V} {
fn items(it: block(K, V)) {
let idx = 0u;
for item: option::t<V> in map.v {
for item in map.v {
alt item {
option::some(elt) {
let value = elt;
let key = idx_key(idx);
put @{key: key, val: value};
it(idx_key(idx), elt);
}
option::none. { }
}
idx += 1u;
}
}
iter keys() -> K {
for each p: @{key: K, val: V} in self.items() { put p.key; }
fn keys(it: block(K)) {
let idx = 0u;
for item in map.v {
if item != option::none { it(idx_key(idx)); }
idx += 1u;
}
}
fn values(it: block(V)) {
for item in map.v {
alt item { option::some(elt) { it(elt); } _ {} }
}
}
}

View File

@ -48,12 +48,8 @@ type scopes = list<scope>;
tag import_state {
todo(ast::node_id, ast::ident, [ast::ident], codemap::span, scopes);
resolving(span);
resolved(option::t<def>,
/* value */
option::t<def>,
/* type */
resolved(option::t<def>, /* value */
option::t<def>, /* type */
option::t<def>); /* module */
}
@ -241,15 +237,14 @@ fn map_crate(e: @env, c: @ast::crate) {
}
fn resolve_imports(e: env) {
for each it: @{key: ast::node_id, val: import_state} in e.imports.items()
{
alt it.val {
e.imports.values {|v|
alt v {
todo(node_id, name, path, span, scopes) {
resolve_import(e, local_def(node_id), name, path, span, scopes);
}
resolved(_, _, _) { }
}
}
};
e.sess.abort_if_errors();
}
@ -1188,12 +1183,9 @@ fn lookup_external(e: env, cnum: int, ids: [ident], ns: namespace) ->
fn check_for_collisions(e: @env, c: ast::crate) {
// Module indices make checking those relatively simple -- just check each
// name for multiple entities in the same namespace.
for each m: @{key: ast::node_id, val: @indexed_mod} in e.mod_map.items() {
for each name: @{key: ident, val: list<mod_index_entry>} in
m.val.index.items() {
check_mod_name(*e, name.key, name.val);
}
}
e.mod_map.values {|val|
val.index.items {|k, v| check_mod_name(*e, k, v); };
};
// Other scopes have to be checked the hard way.
let v =
@{visit_item: bind check_item(e, _, _, _),
@ -1426,7 +1418,7 @@ fn check_bad_exports(e: @env) {
ns_type, inside));
}
for each @{val: val, _} in e.mod_map.items() {
e.mod_map.values {|val|
alt val.m {
some(m) {
for vi in m.view_items {
@ -1447,7 +1439,7 @@ fn check_bad_exports(e: @env) {
}
none. { }
}
}
};
}
// Local Variables:

View File

@ -1249,10 +1249,10 @@ fn make_generic_glue(cx: @local_ctxt, sp: span, t: ty::t, llfn: ValueRef,
}
fn emit_tydescs(ccx: @crate_ctxt) {
for each pair: @{key: ty::t, val: @tydesc_info} in ccx.tydescs.items() {
ccx.tydescs.items {|key, val|
let glue_fn_ty = T_ptr(T_glue_fn(*ccx));
let cmp_fn_ty = T_ptr(T_cmp_glue_fn(*ccx));
let ti = pair.val;
let ti = val;
let take_glue =
alt ti.take_glue {
none. { ccx.stats.n_null_glues += 1u; C_null(glue_fn_ty) }
@ -1274,7 +1274,7 @@ fn emit_tydescs(ccx: @crate_ctxt) {
some(v) { ccx.stats.n_real_glues += 1u; v }
};
let shape = shape::shape_of(ccx, pair.key, ti.ty_params,
let shape = shape::shape_of(ccx, key, ti.ty_params,
ti.is_obj_body);
let shape_tables =
llvm::LLVMConstPointerCast(ccx.shape_cx.llshapetables,
@ -1303,7 +1303,7 @@ fn emit_tydescs(ccx: @crate_ctxt) {
llvm::LLVMSetGlobalConstant(gvar, True);
llvm::LLVMSetLinkage(gvar,
lib::llvm::LLVMInternalLinkage as llvm::Linkage);
}
};
}
fn make_take_glue(cx: @block_ctxt, v: ValueRef, t: ty::t) {
@ -6144,10 +6144,10 @@ fn create_module_map(ccx: @crate_ctxt) -> ValueRef {
llvm::LLVMSetLinkage(map,
lib::llvm::LLVMInternalLinkage as llvm::Linkage);
let elts: [ValueRef] = [];
for each item: @{key: str, val: ValueRef} in ccx.module_data.items() {
let elt = C_struct([p2i(C_cstr(ccx, item.key)), p2i(item.val)]);
ccx.module_data.items {|key, val|
let elt = C_struct([p2i(C_cstr(ccx, key)), p2i(val)]);
elts += [elt];
}
};
let term = C_struct([C_int(0), C_int(0)]);
elts += [term];
llvm::LLVMSetInitializer(map, C_array(elttype, elts));

View File

@ -356,10 +356,10 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
Br(bcx, guard_cx.llbb);
// Temporarily set bindings. They'll be rewritten to PHI nodes for
// the actual arm block.
for each @{key: key, val: val} in data.id_map.items() {
data.id_map.items {|key, val|
let local = local_mem(option::get(assoc(key, m[0].bound)));
bcx.fcx.lllocals.insert(val, local);
}
};
let {bcx: guard_bcx, val: guard_val} =
trans::trans_temp_expr(guard_cx, e);
guard_bcx = trans::trans_block_cleanups(guard_bcx, guard_cx);
@ -582,7 +582,7 @@ fn make_phi_bindings(bcx: @block_ctxt, map: [exit_node],
ids: ast_util::pat_id_map) -> bool {
let our_block = bcx.llbb as uint;
let success = true;
for each @{key: name, val: node_id} in ids.items() {
ids.items {|name, node_id|
let llbbs = [];
let vals = [];
for ex: exit_node in map {
@ -597,10 +597,10 @@ fn make_phi_bindings(bcx: @block_ctxt, map: [exit_node],
let local = Phi(bcx, val_ty(vals[0]), vals, llbbs);
bcx.fcx.lllocals.insert(node_id, local_mem(local));
} else { success = false; }
}
};
if success {
// Copy references that the alias analysis considered unsafe
for each @{val: node_id, _} in ids.items() {
ids.values {|node_id|
if bcx_ccx(bcx).copy_map.contains_key(node_id) {
let local = alt bcx.fcx.lllocals.get(node_id) {
local_mem(x) { x }
@ -613,7 +613,7 @@ fn make_phi_bindings(bcx: @block_ctxt, map: [exit_node],
add_clean(bcx, alloc, e_ty);
bcx.fcx.lllocals.insert(node_id, local_mem(alloc));
}
}
};
} else {
Unreachable(bcx);
}

View File

@ -539,10 +539,9 @@ fn norm_a_constraint(id: def_id, c: constraint) -> [norm_constraint] {
// non-exhaustive match in trans.
fn constraints(fcx: fn_ctxt) -> [norm_constraint] {
let rslt: [norm_constraint] = [];
for each p: @{key: def_id, val: constraint} in
fcx.enclosing.constrs.items() {
rslt += norm_a_constraint(p.key, p.val);
}
fcx.enclosing.constrs.items {|key, val|
rslt += norm_a_constraint(key, val);
};
ret rslt;
}
@ -861,17 +860,16 @@ fn copy_in_poststate_two(fcx: fn_ctxt, src_post: poststate,
}
for each p: @{key: def_id, val: constraint} in
fcx.enclosing.constrs.items() {
fcx.enclosing.constrs.values {|val|
// replace any occurrences of the src def_id with the
// dest def_id
let insts = find_instances(fcx, subst, p.val);
let insts = find_instances(fcx, subst, val);
for p: {from: uint, to: uint} in insts {
if promises_(p.from, src_post) {
set_in_poststate_(p.to, target_post);
}
}
}
};
}

View File

@ -172,12 +172,12 @@ fn use_selectors_to_bind(b: binders, e: @expr) -> option::t<bindings> {
alt sel(match_expr(e)) { none. { ret none; } _ { } }
}
let never_mind: bool = false;
for each pair: @{key: ident, val: selector} in b.real_binders.items() {
alt pair.val(match_expr(e)) {
b.real_binders.items {|key, val|
alt val(match_expr(e)) {
none. { never_mind = true; }
some(mtc) { res.insert(pair.key, mtc); }
some(mtc) { res.insert(key, mtc); }
}
}
};
//HACK: `ret` doesn't work in `for each`
if never_mind { ret none; }
ret some(res);
@ -243,7 +243,7 @@ fn follow_for_trans(cx: ext_ctxt, mmaybe: option::t<arb_depth<matchable>>,
}
/* helper for transcribe_exprs: what vars from `b` occur in `e`? */
iter free_vars(b: bindings, e: @expr) -> ident {
fn free_vars(b: bindings, e: @expr, it: block(ident)) {
let idents: hashmap<ident, ()> = new_str_hash::<()>();
fn mark_ident(&&i: ident, _fld: ast_fold, b: bindings,
idents: hashmap<ident, ()>) -> ident {
@ -257,7 +257,7 @@ iter free_vars(b: bindings, e: @expr) -> ident {
with *default_ast_fold()};
let f = make_fold(f_pre);
f.fold_expr(e); // ignore result
for each id: ident in idents.keys() { put id; }
idents.keys {|x| it(x); };
}
@ -273,7 +273,7 @@ fn transcribe_exprs(cx: ext_ctxt, b: bindings, idx_path: @mutable [uint],
let repeat: option::t<{rep_count: uint, name: ident}> = none;
/* we need to walk over all the free vars in lockstep, except for
the leaves, which are just duplicated */
for each fv: ident in free_vars(b, repeat_me) {
free_vars(b, repeat_me) {|fv|
let cur_pos = follow(b.get(fv), idx_path);
alt cur_pos {
leaf(_) { }
@ -295,7 +295,7 @@ fn transcribe_exprs(cx: ext_ctxt, b: bindings, idx_path: @mutable [uint],
}
}
}
}
};
alt repeat {
none. {
cx.span_fatal(repeat_me.span,

View File

@ -14,8 +14,9 @@ type hashmap<K, V> =
fn find(K) -> option::t<V>;
fn remove(K) -> option::t<V>;
fn rehash();
iter items() -> @{key: K, val: V};
iter keys() -> K;
fn items(block(K, V));
fn keys(block(K));
fn values(block(V));
};
type hashset<K> = hashmap<K, ()>;
@ -111,8 +112,7 @@ fn mk_hashmap<@K, @V>(hasher: hashfn<K>, eqer: eqfn<K>) -> hashmap<K, V> {
}
}
}
obj hashmap<@K,
@V>(hasher: hashfn<K>,
obj hashmap<@K, @V>(hasher: hashfn<K>,
eqer: eqfn<K>,
mutable bkts: [mutable bucket<K, V>],
mutable nbkts: uint,
@ -177,14 +177,19 @@ fn mk_hashmap<@K, @V>(hasher: hashfn<K>, eqer: eqfn<K>) -> hashmap<K, V> {
rehash(hasher, eqer, bkts, nbkts, newbkts, nbkts);
bkts = newbkts;
}
iter items() -> @{key: K, val: V} {
for b: bucket<K, V> in bkts {
alt b { some(k, v) { put @{key: k, val: v}; } _ { } }
fn items(it: block(K, V)) {
for b in bkts {
alt b { some(k, v) { it(copy k, copy v); } _ { } }
}
}
iter keys() -> K {
for b: bucket<K, V> in bkts {
alt b { some(k, _) { put k; } _ { } }
fn keys(it: block(K)) {
for b in bkts {
alt b { some(k, _) { it(copy k); } _ { } }
}
}
fn values(it: block(V)) {
for b in bkts {
alt b { some(_, v) { it(copy v); } _ { } }
}
}
}