diff --git a/include/pocketpy/pocketpy.h b/include/pocketpy/pocketpy.h index a20f9262..2f349d83 100644 --- a/include/pocketpy/pocketpy.h +++ b/include/pocketpy/pocketpy.h @@ -79,8 +79,10 @@ typedef void (*py_TraceFunc)(py_Frame* frame, enum py_TraceEvent); /// A struct contains the callbacks of the VM. typedef struct py_Callbacks { - /// Used by `__import__` to load source code of a module. + /// Used by `__import__` to load a source module. char* (*importfile)(const char*); + /// Called before `importfile` to lazy-import a C module. + py_GlobalRef (*lazyimport)(const char*); /// Used by `print` to output a string. void (*print)(const char*); /// Flush the output buffer of `print`. diff --git a/src/interpreter/vm.c b/src/interpreter/vm.c index adba31d0..234f4e24 100644 --- a/src/interpreter/vm.c +++ b/src/interpreter/vm.c @@ -59,6 +59,7 @@ void VM__ctor(VM* self) { self->main = NULL; self->callbacks.importfile = pk_default_importfile; + self->callbacks.lazyimport = NULL; self->callbacks.print = pk_default_print; self->callbacks.flush = pk_default_flush; self->callbacks.getchr = pk_default_getchr; diff --git a/src/public/modules.c b/src/public/modules.c index 7eb54c46..5856d6a7 100644 --- a/src/public/modules.c +++ b/src/public/modules.c @@ -146,6 +146,15 @@ int py_import(const char* path_cstr) { return true; } + if(vm->callbacks.lazyimport) { + py_GlobalRef lazymod = vm->callbacks.lazyimport(path_cstr); + if(lazymod) { + c11__rtassert(py_istype(lazymod, tp_module)); + py_assign(py_retval(), lazymod); + return 1; + } + } + // try import c11_string* slashed_path = c11_sv__replace(path, '.', PK_PLATFORM_SEP); c11_string* filename = c11_string__new3("%s.py", slashed_path->data);