Skip to content

Instantly share code, notes, and snippets.

@durka
Last active January 15, 2016 20:07
Show Gist options
  • Save durka/2937b09a27f6b6bb7f38 to your computer and use it in GitHub Desktop.
Save durka/2937b09a27f6b6bb7f38 to your computer and use it in GitHub Desktop.
// Utility fn for setting and unsetting the cached id.
fn cache_ids<'a, OP, R>(lctx: &LoweringContext, expr_id: NodeId, op: OP) -> R
where OP: FnOnce(&LoweringContext) -> R
{
// Only reset the id if it was previously 0, i.e., was not cached.
// If it was cached, we are in a nested node, but our id count will
// still count towards the parent's count.
let reset_cached_id = lctx.cached_id.get() == 0;
{
let id_cache: &mut HashMap<_, _> = &mut lctx.id_cache.borrow_mut();
if id_cache.contains_key(&expr_id) {
let cached_id = lctx.cached_id.get();
if cached_id == 0 {
// We're entering a node where we need to track ids, but are not
// yet tracking.
lctx.cached_id.set(id_cache[&expr_id]);
lctx.gensym_key.set(id_cache[&expr_id]);
println!("cache_ids: was in cache, cached_id was 0, now id_cache[{}] = {}, cached_id = {}, gensym_key = {} ({} reset)",
expr_id, id_cache[&expr_id], lctx.cached_id.get(), lctx.gensym_key.get(),
if reset_cached_id { "will" } else { "will not" });
} else {
// We're already tracking - check that the tracked id is the same
// as the expected id.
assert!(cached_id == id_cache[&expr_id], "id mismatch");
println!("cache_ids: was in cache, cached_id was {}, now id_cache[{}] = {}, cached_id = {}, gensym_key = {} ({} reset)",
cached_id, expr_id, id_cache[&expr_id], lctx.cached_id.get(), lctx.gensym_key.get(),
if reset_cached_id { "will" } else { "will not" });
}
} else {
let next_id = lctx.id_assigner.peek_node_id();
id_cache.insert(expr_id, next_id);
//lctx.cached_id.set(next_id);
lctx.gensym_key.set(next_id);
println!("cache_ids: was not in cache, next_id is {}, now id_cache[{}] = {}, cached_id = {}, gensym_key = {} ({} reset)",
next_id, expr_id, id_cache[&expr_id], lctx.cached_id.get(), lctx.gensym_key.get(),
if reset_cached_id { "will" } else { "will not" });
}
}
let result = op(lctx);
if reset_cached_id {
lctx.cached_id.set(0);
lctx.gensym_key.set(0);
println!("cache_ids: resetting, now cached_id = {}, gensym_key = {}",
lctx.cached_id.get(), lctx.gensym_key.get());
} else {
println!("cache_ids, not resetting, now cached_id = {}, gensym_key = {}",
lctx.cached_id.get(), lctx.gensym_key.get());
}
result
}
fn str_to_ident(&self, s: &'static str) -> hir::Ident {
let cached_id = self.gensym_key.get();
if cached_id == 0 {
let result = hir::Ident::from_name(token::gensym(s));
println!("str_to_ident({}) = {:?} (not caching)", s, result);
return result;
}
let cached = self.gensym_cache.borrow().contains_key(&(cached_id, s));
if cached {
let result = self.gensym_cache.borrow()[&(cached_id, s)];
println!("str_to_ident({}) = {:?} (cached, cached_id={})", s, result, cached_id);
result
} else {
let result = hir::Ident::from_name(token::gensym(s));
self.gensym_cache.borrow_mut().insert((cached_id, s), result);
println!("str_to_ident({}) = {:?} (uncached, cached_id={})", s, result, cached_id);
result
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment