Просмотр исходного кода

fix https://github.com/pocketpy/pocketpy/issues/363

blueloveTH 7 месяцев назад
Родитель
Сommit
ca086f9732
3 измененных файлов с 13 добавлено и 1 удалено
  1. 3 1
      include/pocketpy/pocketpy.h
  2. 1 0
      src/interpreter/vm.c
  3. 9 0
      src/public/modules.c

+ 3 - 1
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`.

+ 1 - 0
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;

+ 9 - 0
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);