diff --git a/Cargo.lock b/Cargo.lock index 3cc7835..68302da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1582,9 +1582,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "memmap2" @@ -2380,7 +2380,7 @@ dependencies = [ [[package]] name = "refuse" version = "0.0.1" -source = "git+https://github.com/khonsulabs/refuse#bc969f555fad0f7d2a1ca796475490e40d77415d" +source = "git+https://github.com/khonsulabs/refuse#16bb0cf2a889729d54f61929d706faaf948c5cee" dependencies = [ "crossbeam-utils", "flume", @@ -2393,7 +2393,7 @@ dependencies = [ [[package]] name = "refuse-macros" version = "0.1.0" -source = "git+https://github.com/khonsulabs/refuse#bc969f555fad0f7d2a1ca796475490e40d77415d" +source = "git+https://github.com/khonsulabs/refuse#16bb0cf2a889729d54f61929d706faaf948c5cee" dependencies = [ "attribute-derive 0.9.1", "manyhow 0.11.1", @@ -2405,7 +2405,7 @@ dependencies = [ [[package]] name = "refuse-pool" version = "0.1.0" -source = "git+https://github.com/khonsulabs/refuse#bc969f555fad0f7d2a1ca796475490e40d77415d" +source = "git+https://github.com/khonsulabs/refuse#16bb0cf2a889729d54f61929d706faaf948c5cee" dependencies = [ "ahash", "hashbrown", diff --git a/src/value.rs b/src/value.rs index a1c563c..80144ff 100644 --- a/src/value.rs +++ b/src/value.rs @@ -1121,7 +1121,7 @@ impl AnyDynamic { { (kind.vtable.call)(self, vm, arity.into()) } else { - Ok(Value::Nil) + Err(Fault::ValueFreed) } } diff --git a/src/vm.rs b/src/vm.rs index 07b9b2f..d22a2b9 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -381,14 +381,36 @@ impl<'context, 'guard> VmContext<'context, 'guard> { ) -> Result { let arity = params.load(self)?; - let module_dynamic = self.modules[0] + let mut module_dynamic = self.modules[0] .as_rooted(self.guard) .expect("module missing"); - let module_declarations = module_dynamic.declarations(); - let function = module_declarations - .get(name) - .ok_or_else(|| ExecutionError::new(Fault::UnknownSymbol, self))? - .value; + let mut module_declarations = module_dynamic.declarations(); + let function = if let Some(decl) = module_declarations.get(name) { + decl.value + } else { + let name = name.try_load(self.guard)?; + let mut parts = name.split('.').peekable(); + while let Some(part) = parts.next() { + let part = SymbolRef::from(part); + let Some(decl) = module_declarations.get(&part).map(|decl| decl.value) else { + break; + }; + if parts.peek().is_some() { + let Some(contained_module) = decl.as_rooted::(self.guard) else { + return Err(ExecutionError::new(Fault::UnknownSymbol, self)); + }; + drop(module_declarations); + module_dynamic = contained_module; + module_declarations = module_dynamic.declarations(); + } else { + drop(module_declarations); + return decl + .call(self, arity) + .map_err(|err| ExecutionError::new(err, self)); + } + } + return Err(ExecutionError::new(Fault::UnknownSymbol, self)); + }; drop(module_declarations); let Some(function) = function.as_dynamic::() else { @@ -2217,14 +2239,14 @@ impl Trace for Module { const MAY_CONTAIN_REFERENCES: bool = true; fn trace(&self, tracer: &mut refuse::Tracer) { + println!("Tracing module {:?}", self as *const Self); if let Some(parent) = self.parent { tracer.mark(parent); } for decl in &*self.declarations() { - if let Some(dynamic) = decl.value.value.as_any_dynamic() { - tracer.mark(dynamic); - } + decl.key().trace(tracer); + decl.value.value.trace(tracer); } } }