فهرست منبع

change src module to lazy

blueloveTH 3 سال پیش
والد
کامیت
5a2d389c22
4فایلهای تغییر یافته به همراه33 افزوده شده و 9 حذف شده
  1. 1 1
      src/obj.h
  2. 3 2
      src/pocketpy.h
  3. 23 6
      src/vm.h
  4. 6 0
      tests/random.py

+ 1 - 1
src/obj.h

@@ -10,7 +10,7 @@ const _Int _Int_MAX_NEG = -9223372036854775807LL;
 const _Float _FLOAT_INF_POS = INFINITY;
 const _Float _FLOAT_INF_POS = INFINITY;
 const _Float _FLOAT_INF_NEG = -INFINITY;
 const _Float _FLOAT_INF_NEG = -INFINITY;
 
 
-#define PK_VERSION "0.3.4"
+#define PK_VERSION "0.3.5"
 
 
 class CodeObject;
 class CodeObject;
 class BasePointer;
 class BasePointer;

+ 3 - 2
src/pocketpy.h

@@ -699,10 +699,11 @@ extern "C" {
 
 
     __EXPORT
     __EXPORT
     bool pkpy_add_module(VM* vm, const char* name, const char* source){
     bool pkpy_add_module(VM* vm, const char* name, const char* source){
+        // compile the module but don't execute it
         _Code code = compile(vm, source, name + _Str(".py"));
         _Code code = compile(vm, source, name + _Str(".py"));
         if(code == nullptr) return false;
         if(code == nullptr) return false;
-        PyVar _m = vm->newModule(name);
-        return vm->exec(code, _m) != nullptr;
+        vm->addLazyModule(name, code);
+        return true;
     }
     }
 
 
     void __vm_init(VM* vm){
     void __vm_init(VM* vm){

+ 23 - 6
src/vm.h

@@ -46,7 +46,8 @@ typedef void(*PrintFn)(const VM*, const char*);
 class VM: public PkExportedResource{
 class VM: public PkExportedResource{
 protected:
 protected:
     std::deque< std::unique_ptr<Frame> > callstack;
     std::deque< std::unique_ptr<Frame> > callstack;
-    PyVarDict _modules;       // 3rd modules
+    PyVarDict _modules;                     // loaded modules
+    std::map<_Str, _Code> _lazyModules;     // lazy loaded modules
     PyVar __py2py_call_signal;
     PyVar __py2py_call_signal;
 
 
     PyVar runFrame(Frame* frame){
     PyVar runFrame(Frame* frame){
@@ -329,8 +330,20 @@ protected:
                 {
                 {
                     const _Str& name = frame->code->co_names[byte.arg]->name;
                     const _Str& name = frame->code->co_names[byte.arg]->name;
                     auto it = _modules.find(name);
                     auto it = _modules.find(name);
-                    if(it == _modules.end()) _error("ImportError", "module '" + name + "' not found");
-                    else frame->push(it->second); 
+                    if(it == _modules.end()){
+                        auto it2 = _lazyModules.find(name);
+                        if(it2 == _lazyModules.end()){
+                            _error("ImportError", "module '" + name + "' not found");
+                        }else{
+                            _Code code = it2->second;
+                            PyVar _m = newModule(name);
+                            _exec(code, _m, {});
+                            frame->push(_m);
+                            _lazyModules.erase(it2);
+                        }
+                    }else{
+                        frame->push(it->second);
+                    }
                 } break;
                 } break;
             default:
             default:
                 systemError(_Str("opcode ") + OP_NAMES[byte.op] + " is not implemented");
                 systemError(_Str("opcode ") + OP_NAMES[byte.op] + " is not implemented");
@@ -585,13 +598,17 @@ public:
         return obj;
         return obj;
     }
     }
 
 
-    PyVar newModule(_Str name, bool saveToPath=true) {
+    PyVar newModule(_Str name) {
         PyVar obj = newObject(_tp_module, (_Int)-2);
         PyVar obj = newObject(_tp_module, (_Int)-2);
         setAttr(obj, __name__, PyStr(name));
         setAttr(obj, __name__, PyStr(name));
-        if(saveToPath) _modules[name] = obj;
+        _modules[name] = obj;
         return obj;
         return obj;
     }
     }
 
 
+    void addLazyModule(_Str name, _Code code){
+        _lazyModules[name] = code;
+    }
+
     PyVarOrNull getAttr(const PyVar& obj, const _Str& name, bool throw_err=true) {
     PyVarOrNull getAttr(const PyVar& obj, const _Str& name, bool throw_err=true) {
         PyVarDict::iterator it;
         PyVarDict::iterator it;
         PyObject* cls;
         PyObject* cls;
@@ -792,7 +809,7 @@ public:
         this->True = newObject(_tp_bool, true);
         this->True = newObject(_tp_bool, true);
         this->False = newObject(_tp_bool, false);
         this->False = newObject(_tp_bool, false);
         this->builtins = newModule("builtins");
         this->builtins = newModule("builtins");
-        this->_main = newModule("__main__"_c, false);
+        this->_main = newModule("__main__"_c);
 
 
         setAttr(_tp_type, __base__, _tp_object);
         setAttr(_tp_type, __base__, _tp_object);
         _tp_type->setType(_tp_type);
         _tp_type->setType(_tp_type);

+ 6 - 0
tests/random.py

@@ -0,0 +1,6 @@
+import random
+
+for _ in range(100):
+    i = random.randint(1, 10)
+    assert i <= 10
+    assert i >= 1