Commit 4adf0c46 authored by twanvl's avatar twanvl

Fixed bug in dependency checker that caused it to overwrite variables outside its scope

parent 9c763a82
...@@ -265,12 +265,22 @@ ScriptValueP Context::makeClosure(const ScriptValueP& fun) { ...@@ -265,12 +265,22 @@ ScriptValueP Context::makeClosure(const ScriptValueP& fun) {
size_t Context::openScope() { size_t Context::openScope() {
level += 1; level += 1;
#ifdef _DEBUG
scopes.push_back(shadowed.size());
assert(scopes.size() == level);
#endif
return shadowed.size(); return shadowed.size();
} }
void Context::closeScope(size_t scope) { void Context::closeScope(size_t scope) {
assert(level > 0); assert(level > 0);
assert(scope <= shadowed.size()); assert(scope <= shadowed.size());
level -= 1; level -= 1;
#ifdef _DEBUG
assert(!scopes.empty());
assert(scopes.back() == scope);
scopes.pop_back();
assert(scopes.size() == level);
#endif
// restore shadowed variables // restore shadowed variables
while (shadowed.size() > scope) { while (shadowed.size() > scope) {
variables[shadowed.back().variable] = shadowed.back().value; variables[shadowed.back().variable] = shadowed.back().value;
......
...@@ -103,6 +103,10 @@ class Context { ...@@ -103,6 +103,10 @@ class Context {
unsigned int level; unsigned int level;
/// Stack of values /// Stack of values
vector<ScriptValueP> stack; vector<ScriptValueP> stack;
#ifdef _DEBUG
/// The opened scopes, for sanity checking
vector<size_t> scopes;
#endif
// utility types for dependency analysis // utility types for dependency analysis
struct Jump; struct Jump;
......
...@@ -159,7 +159,7 @@ ScriptValueP Context::dependencies(const Dependency& dep, const Script& script) ...@@ -159,7 +159,7 @@ ScriptValueP Context::dependencies(const Dependency& dep, const Script& script)
} }
// unify bindings // unify bindings
FOR_EACH(v, j->bindings) { FOR_EACH(v, j->bindings) {
unify(variables[v.variable].value, v.value.value); setVariable(v.variable, unified(variables[v.variable].value, v.value.value) );
} }
delete j; delete j;
} }
...@@ -368,9 +368,8 @@ void Context::getBindings(size_t scope, vector<Binding>& bindings) { ...@@ -368,9 +368,8 @@ void Context::getBindings(size_t scope, vector<Binding>& bindings) {
} }
void Context::resetBindings(size_t scope) { void Context::resetBindings(size_t scope) {
// same as closeScope() // close and re-open the scope
while (shadowed.size() > scope) { closeScope(scope);
variables[shadowed.back().variable] = shadowed.back().value; size_t same_scope = openScope();
shadowed.pop_back(); assert(scope == same_scope);
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment