nac3artiq: move module registration list to CPython side

In ARTIQ, we cannot create a global NAC3 object because we do not
know the ISA in advance.
This commit is contained in:
Sebastien Bourdeauducq 2021-11-07 10:29:14 +08:00
parent ffa89e9308
commit 50f1aca1aa
2 changed files with 8 additions and 19 deletions

View File

@ -17,7 +17,7 @@ core_arguments = device_db.device_db["core"]["arguments"]
compiler = nac3artiq.NAC3(core_arguments["target"]) compiler = nac3artiq.NAC3(core_arguments["target"])
allow_module_registration = True allow_module_registration = True
registered_ids = set() registered_modules = set()
T = TypeVar('T') T = TypeVar('T')
@ -26,13 +26,9 @@ class KernelInvariant(Generic[T]):
def register_module_of(obj): def register_module_of(obj):
global registered_ids
assert allow_module_registration assert allow_module_registration
module = getmodule(obj) # Delay NAC3 analysis until all referenced variables are supposed to exist on the CPython side.
module_id = id(module) registered_modules.add(getmodule(obj))
if module_id not in registered_ids:
compiler.register_module(module)
registered_ids.add(module_id)
def extern(function): def extern(function):
@ -111,7 +107,7 @@ class Core:
def run(self, method, *args, **kwargs): def run(self, method, *args, **kwargs):
global allow_module_registration global allow_module_registration
if allow_module_registration: if allow_module_registration:
compiler.analyze() compiler.analyze_modules(registered_modules)
allow_module_registration = False allow_module_registration = False
if hasattr(method, "__self__"): if hasattr(method, "__self__"):

View File

@ -9,7 +9,7 @@ use inkwell::{
OptimizationLevel, OptimizationLevel,
}; };
use pyo3::prelude::*; use pyo3::prelude::*;
use pyo3::{exceptions, types::PyList, types::PyBytes}; use pyo3::{exceptions, types::PyList, types::PySet, types::PyBytes};
use nac3parser::{ use nac3parser::{
ast::{self, StrRef}, ast::{self, StrRef},
parser::{self, parse_program}, parser::{self, parse_program},
@ -66,7 +66,6 @@ struct Nac3 {
pyid_to_type: Arc<RwLock<HashMap<u64, Type>>>, pyid_to_type: Arc<RwLock<HashMap<u64, Type>>>,
composer: TopLevelComposer, composer: TopLevelComposer,
top_level: Option<Arc<TopLevelContext>>, top_level: Option<Arc<TopLevelContext>>,
to_be_registered: Vec<PyObject>,
primitive_ids: PrimitivePythonId, primitive_ids: PrimitivePythonId,
global_value_ids: Arc<Mutex<HashSet<u64>>>, global_value_ids: Arc<Mutex<HashSet<u64>>>,
working_directory: TempDir, working_directory: TempDir,
@ -299,20 +298,14 @@ impl Nac3 {
top_level: None, top_level: None,
pyid_to_def: Default::default(), pyid_to_def: Default::default(),
pyid_to_type: Default::default(), pyid_to_type: Default::default(),
to_be_registered: Default::default(),
global_value_ids: Default::default(), global_value_ids: Default::default(),
working_directory working_directory
}) })
} }
fn register_module(&mut self, obj: PyObject) { fn analyze_modules(&mut self, modules: &PySet) -> PyResult<()> {
// Delay registration until all referenced variables are supposed to exist on the CPython side for obj in modules.iter() {
self.to_be_registered.push(obj); self.register_module_impl(obj.into())?;
}
fn analyze(&mut self) -> PyResult<()> {
for obj in std::mem::take(&mut self.to_be_registered).into_iter() {
self.register_module_impl(obj)?;
} }
Ok(()) Ok(())
} }