blueloveTH před 3 roky
rodič
revize
2e943f0e34
5 změnil soubory, kde provedl 25 přidání a 18 odebrání
  1. 7 1
      src/codeobject.h
  2. 1 1
      src/pocketpy.h
  3. 2 2
      src/pointer.h
  4. 1 1
      src/repl.h
  5. 14 13
      src/vm.h

+ 7 - 1
src/codeobject.h

@@ -125,6 +125,8 @@ public:
     PyVar _module;
     PyVarDict f_locals;
 
+    uint64_t id;
+
     inline PyVarDict& f_globals(){
         return _module->attribs;
     }
@@ -132,7 +134,11 @@ public:
     const CodeObject* code;
 
     Frame(const CodeObject* code, PyVar _module, const PyVarDict& locals)
-        : code(code), _module(_module), f_locals(locals) {}
+        : code(code), _module(_module), f_locals(locals) {
+        
+        static uint64_t frame_id = 1;
+        id = frame_id++;
+    }
 
     inline const ByteCode& readCode() {
         return code->co_code[ip++];

+ 1 - 1
src/pocketpy.h

@@ -704,7 +704,7 @@ extern "C" {
         __initializeBuiltinFunctions(vm);
         _Code code = compile(vm, __BUILTINS_CODE, "<builtins>");
         if(code == nullptr) exit(1);
-        vm->_exec(code, vm->builtins);
+        vm->_exec(code, vm->builtins, {});
 
         __addModuleSys(vm);
         __addModuleTime(vm);

+ 2 - 2
src/pointer.h

@@ -62,8 +62,8 @@ struct CompoundPointer : BasePointer {
 
 struct UserPointer : BasePointer {
     const _Pointer p;
-    Frame* frame;
-    UserPointer(_Pointer p, Frame* frame) : p(p), frame(frame) {}
+    uint64_t f_id;
+    UserPointer(_Pointer p, uint64_t f_id) : p(p), f_id(f_id) {}
 
     PyVar get(VM* vm, Frame* frame) const;
     void set(VM* vm, Frame* frame, PyVar val) const;

+ 1 - 1
src/repl.h

@@ -62,7 +62,7 @@ __NOT_ENOUGH_LINES:
 
         try{
             _Code code = compile(vm, line.c_str(), "<stdin>", mode);
-            if(code != nullptr) vm->exec(code);
+            if(code != nullptr) vm->exec(code, nullptr, true);
         }catch(NeedMoreLines& ne){
             buffer += line;
             buffer += '\n';

+ 14 - 13
src/vm.h

@@ -211,7 +211,7 @@ private:
                 {
                     // _pointer to pointer
                     const _Pointer& p = PyPointer_AS_C(frame->__pop());
-                    _Pointer up = std::make_shared<UserPointer>(p, frame);
+                    _Pointer up = std::make_shared<UserPointer>(p, frame->id);
                     frame->push(newObject(_tp_user_pointer, std::move(up)));
                 } break;
             case OP_UNARY_DEREF:
@@ -373,11 +373,13 @@ public:
         return asRepr(obj);
     }
 
-    bool __isFrameValid(Frame* frame){
+    Frame* __findFrame(uint64_t up_f_id){
         for(auto it=callstack.crbegin(); it!=callstack.crend(); ++it){
-            if(it->get() == frame) return true;
+            uint64_t f_id = it->get()->id;
+            if(f_id == up_f_id) return it->get();
+            if(f_id < up_f_id) return nullptr;
         }
-        return false;
+        return nullptr;
     }
 
     Frame* topFrame(){
@@ -498,10 +500,10 @@ public:
         return call(getAttr(obj, func), args);
     }
 
-    PyVarOrNull exec(const _Code& code, PyVar _module=nullptr){
+    PyVarOrNull exec(const _Code& code, PyVar _module=nullptr, bool repl_mode=false){
         if(_module == nullptr) _module = _main;
         try {
-            return _exec(code, _module);
+            return _exec(code, _module, {}, repl_mode);
         } catch (const std::exception& e) {
             if(const _Error* _ = dynamic_cast<const _Error*>(&e)){
                 *_stderr << e.what() << '\n';
@@ -523,8 +525,9 @@ public:
         return frame;
     }
 
-    PyVar _exec(const _Code& code, PyVar _module, const PyVarDict& locals={}){
+    PyVar _exec(const _Code& code, PyVar _module, const PyVarDict& locals, bool repl_mode=false){
         Frame* frame = __pushNewFrame(code, _module, locals);
+        if(repl_mode) frame->id = 0;
         Frame* frameBase = frame;
         PyVar ret = nullptr;
 
@@ -956,16 +959,14 @@ void CompoundPointer::del(VM* vm, Frame* frame) const{
 }
 
 PyVar UserPointer::get(VM* vm, Frame* frame) const{
-    frame = this->frame;
-    // this check is unsafe, but it's the best we can do
-    if(!vm->__isFrameValid(frame)) vm->nullPointerError();
+    frame = vm->__findFrame(f_id);
+    if(frame == nullptr) vm->nullPointerError();
     return p->get(vm, frame);
 }
 
 void UserPointer::set(VM* vm, Frame* frame, PyVar val) const{
-    frame = this->frame;
-    // this check is unsafe, but it's the best we can do
-    if(!vm->__isFrameValid(frame)) vm->nullPointerError();
+    frame = vm->__findFrame(f_id);
+    if(frame == nullptr) vm->nullPointerError();
     p->set(vm, frame, val);
 }