diff --git a/artiq/coredevice/core.py b/artiq/coredevice/core.py index a7ea27269..dcd9c9ef8 100644 --- a/artiq/coredevice/core.py +++ b/artiq/coredevice/core.py @@ -102,7 +102,11 @@ class Core: raise NotImplementedError if not self.analyzed: - self.compiler.analyze(core_language._registered_functions, core_language._registered_classes) + self.compiler.analyze( + core_language._registered_functions, + core_language._registered_classes, + core_language._registered_modules + ) self.analyzed = True if hasattr(method, "__self__"): diff --git a/artiq/language/core.py b/artiq/language/core.py index a3f9faa03..7e970e420 100644 --- a/artiq/language/core.py +++ b/artiq/language/core.py @@ -56,6 +56,7 @@ def ceil64(x): # Delay NAC3 analysis until all referenced variables are supposed to exist on the CPython side. _registered_functions = set() _registered_classes = set() +_registered_modules = set() def _register_function(fun): import_cache.add_module_to_cache(getmodule(fun)) @@ -65,6 +66,11 @@ def _register_class(cls): import_cache.add_module_to_cache(getmodule(cls)) _registered_classes.add(cls) +def register_content_module(module): + # for kernels sent by content, they have no modules + # thus their source must be analyzed instead + _registered_modules.add(module) + def extern(function): """Decorates a function declaration defined by the core device runtime.""" diff --git a/artiq/master/worker_impl.py b/artiq/master/worker_impl.py index 86f08b060..916c43728 100644 --- a/artiq/master/worker_impl.py +++ b/artiq/master/worker_impl.py @@ -30,7 +30,9 @@ from artiq.master.worker_db import DeviceManager, DatasetManager, DummyDevice from artiq.language.environment import ( is_public_experiment, TraceArgumentManager, ProcessArgumentManager ) -from artiq.language.core import set_watchdog_factory, TerminationRequested +from artiq.language.core import ( + register_content_module, set_watchdog_factory, TerminationRequested +) from artiq.language import import_cache from artiq import __version__ as artiq_version @@ -166,6 +168,7 @@ def get_experiment_from_content(content, class_name): StringLoader(fake_filename, content) ) module = importlib.util.module_from_spec(spec) + register_content_module(module) spec.loader.exec_module(module) linecache.lazycache(fake_filename, module.__dict__) return tools.get_experiment(module, class_name)