From 2e943f0e347b46c0546ce72f2cae2e1da3ee78f1 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Mon, 21 Nov 2022 00:30:40 +0800 Subject: [PATCH] up --- src/codeobject.h | 8 +++++++- src/pocketpy.h | 2 +- src/pointer.h | 4 ++-- src/repl.h | 2 +- src/vm.h | 27 ++++++++++++++------------- 5 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/codeobject.h b/src/codeobject.h index a4561ed0..a949f5bc 100644 --- a/src/codeobject.h +++ b/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++]; diff --git a/src/pocketpy.h b/src/pocketpy.h index 17f0042d..489f03f2 100644 --- a/src/pocketpy.h +++ b/src/pocketpy.h @@ -704,7 +704,7 @@ extern "C" { __initializeBuiltinFunctions(vm); _Code code = compile(vm, __BUILTINS_CODE, ""); if(code == nullptr) exit(1); - vm->_exec(code, vm->builtins); + vm->_exec(code, vm->builtins, {}); __addModuleSys(vm); __addModuleTime(vm); diff --git a/src/pointer.h b/src/pointer.h index 74b3d82a..35a8ba87 100644 --- a/src/pointer.h +++ b/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; diff --git a/src/repl.h b/src/repl.h index fa485c9e..7b89e5bc 100644 --- a/src/repl.h +++ b/src/repl.h @@ -62,7 +62,7 @@ __NOT_ENOUGH_LINES: try{ _Code code = compile(vm, line.c_str(), "", mode); - if(code != nullptr) vm->exec(code); + if(code != nullptr) vm->exec(code, nullptr, true); }catch(NeedMoreLines& ne){ buffer += line; buffer += '\n'; diff --git a/src/vm.h b/src/vm.h index 5e5cd425..077ab7dd 100644 --- a/src/vm.h +++ b/src/vm.h @@ -211,7 +211,7 @@ private: { // _pointer to pointer const _Pointer& p = PyPointer_AS_C(frame->__pop()); - _Pointer up = std::make_shared(p, frame); + _Pointer up = std::make_shared(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(&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); }