Implement name mangling logic in symbol_resolver

This commit is contained in:
Siddhangana 2024-12-19 13:15:05 +08:00
parent 1531b6cc98
commit 7ad72b7eea
2 changed files with 25 additions and 5 deletions

View File

@ -102,6 +102,15 @@ impl<'a> ArtiqCodeGenerator<'a> {
} }
} }
/// To resolve class name dynamically - name field is used to obtain class name
pub fn get_class_name(&self) -> Option<String> {
if self.name.is_empty() {
None
} else {
Some(self.name.clone())
}
}
/// If the generator is currently in a direct-`parallel` block context, emits IR that resets the /// If the generator is currently in a direct-`parallel` block context, emits IR that resets the
/// position of the timeline to the initial timeline position before entering the `parallel` /// position of the timeline to the initial timeline position before entering the `parallel`
/// block. /// block.

View File

@ -1516,9 +1516,20 @@ impl SymbolResolver for Resolver {
_: &mut CodeGenContext<'ctx, '_>, _: &mut CodeGenContext<'ctx, '_>,
_: &mut dyn CodeGenerator, _: &mut dyn CodeGenerator,
) -> Option<ValueEnum<'ctx>> { ) -> Option<ValueEnum<'ctx>> {
let (resolved_id, is_dunder) = if id.starts_with("__") && !id.ends_with("__") && !id.to_string().contains('.') {
if let Some(class_name) = self.get_class_name() {
let stripped_class_name = class_name.trim_start_matches('_');
let mangled_id: StrRef = format!("_{}{}", stripped_class_name, id).into();
(mangled_id, true)
} else {
(id, false)
}
} else {
(id, false)
};
let sym_value = { let sym_value = {
let id_to_val = self.0.id_to_pyval.read(); let id_to_val = self.0.id_to_pyval.read();
id_to_val.get(&id).cloned() id_to_val.get(&resolved_id).cloned()
} }
.or_else(|| { .or_else(|| {
Python::with_gil(|py| -> PyResult<Option<(u64, PyObject)>> { Python::with_gil(|py| -> PyResult<Option<(u64, PyObject)>> {
@ -1527,14 +1538,14 @@ impl SymbolResolver for Resolver {
let members: &PyDict = obj.getattr("__dict__").unwrap().downcast().unwrap(); let members: &PyDict = obj.getattr("__dict__").unwrap().downcast().unwrap();
for (key, val) in members { for (key, val) in members {
let key: &str = key.extract()?; let key: &str = key.extract()?;
if key == id.to_string() { if key == resolved_id.to_string() {
let id = self.0.helper.id_fn.call1(py, (val,))?.extract(py)?; let pyid = self.0.helper.id_fn.call1(py, (val,))?.extract(py)?;
sym_value = Some((id, val.extract()?)); sym_value = Some((pyid, val.extract()?));
break; break;
} }
} }
if let Some((pyid, val)) = &sym_value { if let Some((pyid, val)) = &sym_value {
self.0.id_to_pyval.write().insert(id, (*pyid, val.clone())); self.0.id_to_pyval.write().insert(resolved_id, (*pyid, val.clone()));
} }
Ok(sym_value) Ok(sym_value)
}) })