Skip to content

Commit

Permalink
feat: Add an iterator over upvariable names
Browse files Browse the repository at this point in the history
  • Loading branch information
Marwes committed Jan 22, 2017
1 parent 4f056be commit a098c90
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 0 deletions.
37 changes: 37 additions & 0 deletions tests/debug.rs
Expand Up @@ -189,3 +189,40 @@ fn source_name() {
let name = result.lock().unwrap();
assert_eq!(*name, "test");
}


#[test]
fn upvars() {
let _ = env_logger::init();

let thread = new_vm();
let result = Arc::new(Mutex::new(Vec::new()));
{
let result = result.clone();
let mut context = thread.context();
context.set_hook(Some(Box::new(move |_, debug_info| {
let stack_info = debug_info.stack_info(0).unwrap();
if stack_info.source_name() == "test" {
result.lock().unwrap().push(stack_info.upvars().to_owned());
}
Ok(())
})));
context.set_hook_mask(CALL_FLAG);
}
let expr = r#"
let x = 1
let y = 2
let f z =
let g w = x
g x + y + z
f 3
"#;
Compiler::new()
.run_expr::<i32>(&thread, "test", expr)
.unwrap();

assert_eq!(*result.lock().unwrap(),
vec![vec![],
vec!["x".to_string(), "+".to_string(), "y".to_string()],
vec!["x".to_string()]]);
}
8 changes: 8 additions & 0 deletions vm/src/compiler.rs
Expand Up @@ -48,6 +48,7 @@ pub struct CompiledFunction {
/// Maps instruction indexes to the line that spawned them
pub source_map: SourceMap,
pub local_map: LocalMap,
pub upvar_names: Vec<String>,
pub source_name: String,
}

Expand All @@ -65,6 +66,7 @@ impl CompiledFunction {
records: Vec::new(),
source_map: SourceMap::new(),
local_map: LocalMap::new(),
upvar_names: Vec::new(),
source_name: source_name,
}
}
Expand Down Expand Up @@ -120,6 +122,12 @@ impl FunctionEnvs {
compiler.stack_constructors.exit_scope();
let instructions = self.function.instructions.len();
self.function.source_map.close(instructions, current_line);
{
let function = &mut **self;
function.function
.upvar_names
.extend(function.free_vars.iter().map(|s| s.declared_name().to_string()));
}
self.envs.pop().expect("FunctionEnv in scope")
}
}
Expand Down
7 changes: 7 additions & 0 deletions vm/src/thread.rs
Expand Up @@ -756,6 +756,13 @@ impl<'a> StackInfo<'a> {
_ => LocalIter::empty(),
}
}

pub fn upvars(&self) -> &[StdString] {
match self.frame().state {
State::Closure(ref closure) => &closure.function.upvar_names,
_ => panic!("Attempted to access upvar in non closure function"),
}
}
}

bitflags! {
Expand Down
1 change: 1 addition & 0 deletions vm/src/value.rs
Expand Up @@ -119,6 +119,7 @@ pub struct BytecodeFunction {
pub records: Vec<Vec<InternedStr>>,
pub source_map: SourceMap,
pub local_map: LocalMap,
pub upvar_names: Vec<StdString>,
pub source_name: StdString,
}

Expand Down
2 changes: 2 additions & 0 deletions vm/src/vm.rs
Expand Up @@ -42,6 +42,7 @@ fn new_bytecode(gc: &mut Gc,
records,
source_map,
local_map,
upvar_names,
source_name,
.. } = f;

Expand Down Expand Up @@ -72,6 +73,7 @@ fn new_bytecode(gc: &mut Gc,
records: records?,
source_map: source_map,
local_map: local_map,
upvar_names: upvar_names,
source_name: source_name,
}))
}
Expand Down

0 comments on commit a098c90

Please sign in to comment.