Fix bug where global names could only be used once in the root scope
Global names previously would only load once, and then not again because of issues with how the root scope is compiled. This is fixed. Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -104,6 +104,10 @@ impl Compile {
|
||||
pub(crate) fn collect_locals(&mut self, body: &Body) {
|
||||
locals::CollectLocals::new(self).collect(body);
|
||||
}
|
||||
|
||||
pub(crate) fn scope(&self) -> &Scope {
|
||||
&self.scope
|
||||
}
|
||||
}
|
||||
|
||||
/// Constant data pool used for building the const pool.
|
||||
|
||||
@@ -69,4 +69,8 @@ impl Scope {
|
||||
pub fn globals_mut(&mut self) -> Option<&mut ScopeLocalSyms> {
|
||||
self.scope.first_mut()
|
||||
}
|
||||
|
||||
pub fn layers_len(&self) -> usize {
|
||||
self.scope.len()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,12 +419,21 @@ impl Visit for CompileBody<'_> {
|
||||
let thunk = match atom {
|
||||
Atom::Ident(ident) => {
|
||||
let sym = global_sym(ident.to_string());
|
||||
// TODO : use "LOAD_GLOBAL" instead of "LOAD_LOCAL" when inside a user function
|
||||
if let Some(local) = self.compile.lookup_local(sym) {
|
||||
// Small gotcha:
|
||||
// Looking up a name will either result in a local or a global lookup. If it's
|
||||
// a local variable first, then it's determined as a local and that's the end
|
||||
// of the story... except when we're at the top scope level, we're both "local"
|
||||
// *and* global.
|
||||
//
|
||||
// This checks to make sure that it's both a local variable and that there's more
|
||||
// than one scope layer.
|
||||
if let (true, Some(local)) = (self.compile.scope().layers_len() > 1, self.compile.lookup_local(sym)) {
|
||||
// get local
|
||||
Inst::LoadLocal(local).into()
|
||||
} else {
|
||||
// get or create global
|
||||
// create_global only makes a new global with this symbol name if one has not
|
||||
// been created yet
|
||||
let global = self.compile.create_global(sym);
|
||||
Inst::LoadGlobal(global).into()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user