From 5f4d47721a5cc19ff2690bad36ed1bfeee328173 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Fri, 2 Dec 2022 01:56:05 +0800 Subject: [PATCH] some fix --- src/main.cpp | 2 +- src/obj.h | 3 +-- src/pocketpy.h | 51 +++++++++++++++++++++++++++++++++++---------- src/pointer.h | 2 +- src/repl.h | 2 +- src/vm.h | 56 ++++++++++++++++++-------------------------------- 6 files changed, 64 insertions(+), 52 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 1c3a008d..8dfa4fdf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -94,7 +94,7 @@ int main(int argc, char** argv){ std::string src((std::istreambuf_iterator(file)), std::istreambuf_iterator()); ThreadedVM* vm = pkpy_new_tvm(true); - _Code code; + _Code code = nullptr; Timer("Compile time").run([&]{ code = compile(vm, src.c_str(), filename); }); diff --git a/src/obj.h b/src/obj.h index bd0b5020..ed29a9eb 100644 --- a/src/obj.h +++ b/src/obj.h @@ -5,13 +5,12 @@ typedef int64_t _Int; typedef double _Float; -#define PK_VERSION "0.4.0" +#define PK_VERSION "0.4.5" class CodeObject; class BasePointer; class VM; class Frame; -class PkExportedResource {}; typedef std::shared_ptr _Pointer; typedef PyVar (*_CppFunc)(VM*, const pkpy::ArgList&); diff --git a/src/pocketpy.h b/src/pocketpy.h index 711a9d2f..ce8627bd 100644 --- a/src/pocketpy.h +++ b/src/pocketpy.h @@ -630,9 +630,33 @@ void __addModuleSys(VM* vm){ vm->setAttr(mod, "version", vm->PyStr(PK_VERSION)); } +class _PkExported; +static std::vector<_PkExported*> _pkLookupTable; +class _PkExported{ +public: + virtual ~_PkExported() = default; + virtual void* get() = 0; +}; + +template +class PkExported : public _PkExported{ + T* _ptr; +public: + template + PkExported(Args&&... args) : _ptr(new T(std::forward(args)...)){ + _pkLookupTable.push_back(this); + } + + ~PkExported() override { delete _ptr; } + void* get() override { return _ptr; } + operator T*() { return _ptr; } +}; + +#define pkpy_allocate(T, ...) *(new PkExported(__VA_ARGS__)) + extern "C" { - struct PyObjectDump: public PkExportedResource{ + struct PyObjectDump { const char* type; // "int", "str", "float" ... const char* json; // json representation @@ -647,7 +671,7 @@ extern "C" { } }; - struct PyOutputDump: public PkExportedResource{ + struct PyOutputDump { const char* _stdout; const char* _stderr; @@ -663,8 +687,13 @@ extern "C" { }; __EXPORT - void pkpy_delete(PkExportedResource* p){ - delete p; + void pkpy_delete(void* p){ + for(int i = 0; i < _pkLookupTable.size(); i++){ + if(_pkLookupTable[i]->get() == p){ + delete _pkLookupTable[i]; + _pkLookupTable.erase(_pkLookupTable.begin() + i); + } + } } __EXPORT @@ -686,7 +715,7 @@ extern "C" { PyObjectDump* pkpy_get_global(VM* vm, const char* name){ auto it = vm->_main->attribs.find(name); if(it == vm->_main->attribs.end()) return nullptr; - return new PyObjectDump( + return pkpy_allocate(PyObjectDump, it->second->getTypeName().c_str(), vm->PyStr_AS_C(vm->asJson(it->second)).c_str() ); @@ -698,7 +727,7 @@ extern "C" { if(code == nullptr) return nullptr; PyVarOrNull ret = vm->exec(code); if(ret == nullptr) return nullptr; - return new PyObjectDump( + return pkpy_allocate(PyObjectDump, ret->getTypeName(), vm->PyStr_AS_C(vm->asJson(ret)) ); @@ -706,7 +735,7 @@ extern "C" { __EXPORT REPL* pkpy_new_repl(VM* vm){ - return new REPL(vm); + return pkpy_allocate(REPL, vm); } __EXPORT @@ -736,14 +765,14 @@ extern "C" { __EXPORT VM* pkpy_new_vm(bool use_stdio){ - VM* vm = new VM(use_stdio); + VM* vm = pkpy_allocate(VM, use_stdio); __vm_init(vm); return vm; } __EXPORT ThreadedVM* pkpy_new_tvm(bool use_stdio){ - ThreadedVM* vm = new ThreadedVM(use_stdio); + ThreadedVM* vm = pkpy_allocate(ThreadedVM, use_stdio); __vm_init(vm); return vm; } @@ -754,7 +783,7 @@ extern "C" { _StrStream* s_out = dynamic_cast<_StrStream*>(vm->_stdout); _StrStream* s_err = dynamic_cast<_StrStream*>(vm->_stderr); if(s_out == nullptr || s_err == nullptr) return nullptr; - PyOutputDump* dump = new PyOutputDump(s_out->str(), s_err->str()); + PyOutputDump* dump = pkpy_allocate(PyOutputDump, s_out->str(), s_err->str()); s_out->str(""); s_err->str(""); return dump; @@ -774,7 +803,7 @@ extern "C" { PyObjectDump* pkpy_tvm_read_json(ThreadedVM* vm){ std::optional<_Str> s = vm->readSharedStr(); if(!s.has_value()) return nullptr; - return new PyObjectDump("str"_c, s.value()); + return pkpy_allocate(PyObjectDump, "str"_c, s.value()); } __EXPORT diff --git a/src/pointer.h b/src/pointer.h index 35a8ba87..8aea3a9c 100644 --- a/src/pointer.h +++ b/src/pointer.h @@ -52,7 +52,7 @@ struct IndexPointer : BasePointer { struct CompoundPointer : BasePointer { const std::vector<_Pointer> pointers; - CompoundPointer(std::vector<_Pointer> pointers) : pointers(pointers) {} + CompoundPointer(const std::vector<_Pointer>& pointers) : pointers(pointers) {} CompoundPointer(std::vector<_Pointer>&& pointers) : pointers(pointers) {} PyVar get(VM* vm, Frame* frame) const; diff --git a/src/repl.h b/src/repl.h index 3edd88cd..8e15f5e5 100644 --- a/src/repl.h +++ b/src/repl.h @@ -9,7 +9,7 @@ enum InputResult { EXEC_SKIPPED = 2, }; -class REPL: public PkExportedResource { +class REPL { protected: int need_more_lines = 0; std::string buffer; diff --git a/src/vm.h b/src/vm.h index 7eebbdb1..98ee9120 100644 --- a/src/vm.h +++ b/src/vm.h @@ -19,32 +19,11 @@ __DEF_PY(type, ctype, ptype) \ __DEF_PY_AS_C(type, ctype, ptype) -#define __DEF_PY_POOL(name, ctype, ptype, max_size) \ - std::vector _pool##name; \ - PyVar Py##name(ctype _native) { \ - PyObject* _raw = nullptr; \ - if(_pool##name.size() > 0) { \ - _raw = _pool##name.back(); \ - _raw->_native = std::move(_native); \ - _pool##name.pop_back(); \ - }else{ \ - __checkType(ptype, _tp_type); \ - _raw = new PyObject(std::move(_native));\ - _raw->setType(ptype); \ - } \ - return PyVar(_raw, [this](PyObject* p){ \ - if(_pool##name.size() < max_size){ \ - _pool##name.push_back(p); \ - }else{ \ - delete p; \ - } \ - }); \ - } - typedef void(*PrintFn)(const VM*, const char*); -class VM: public PkExportedResource{ +class VM { std::atomic _stopFlag = false; + std::vector _smallIntegers; // [-5, 256] protected: std::deque< std::unique_ptr > callstack; PyVarDict _modules; // loaded modules @@ -100,11 +79,11 @@ protected: } break; case OP_STORE_PTR: { PyVar obj = frame->popValue(this); - const _Pointer& p = PyPointer_AS_C(frame->__pop()); + const _Pointer p = PyPointer_AS_C(frame->__pop()); p->set(this, frame, std::move(obj)); } break; case OP_DELETE_PTR: { - const _Pointer& p = PyPointer_AS_C(frame->__pop()); + const _Pointer p = PyPointer_AS_C(frame->__pop()); p->del(this, frame); } break; case OP_BUILD_SMART_TUPLE: @@ -170,7 +149,7 @@ protected: case OP_RETURN_VALUE: return frame->popValue(this); case OP_PRINT_EXPR: { - const PyVar& expr = frame->topValue(this); + const PyVar expr = frame->topValue(this); if(expr == None) break; *_stdout << PyStr_AS_C(asRepr(expr)) << '\n'; } break; @@ -228,7 +207,7 @@ protected: case OP_UNARY_REF: { // _pointer to pointer - const _Pointer& p = PyPointer_AS_C(frame->__pop()); + const _Pointer p = PyPointer_AS_C(frame->__pop()); _Pointer up = std::make_shared(p, frame->id); frame->push(newObject(_tp_user_pointer, std::move(up))); } break; @@ -317,13 +296,13 @@ protected: } break; case OP_JUMP_IF_FALSE_OR_POP: { - const PyVar& expr = frame->topValue(this); + const PyVar expr = frame->topValue(this); if(asBool(expr)==False) frame->jump(byte.arg); else frame->popValue(this); } break; case OP_JUMP_IF_TRUE_OR_POP: { - const PyVar& expr = frame->topValue(this); + const PyVar expr = frame->topValue(this); if(asBool(expr)==True) frame->jump(byte.arg); else frame->popValue(this); } break; @@ -407,6 +386,9 @@ public: this->_stderr = new _StrStream(); } initializeBuiltinClasses(); + + _smallIntegers.reserve(300); + for(_Int i=-5; i<=256; i++) _smallIntegers.push_back(newObject(_tp_int, i)); } void keyboardInterrupt(){ @@ -784,18 +766,20 @@ public: PyVar _tp_slice, _tp_range, _tp_module, _tp_pointer; PyVar _tp_user_pointer, _tp_super; - __DEF_PY_POOL(Int, _Int, _tp_int, 256); - __DEF_PY_AS_C(Int, _Int, _tp_int) - __DEF_PY_POOL(Float, _Float, _tp_float, 256); - __DEF_PY_AS_C(Float, _Float, _tp_float) - __DEF_PY_POOL(Pointer, _Pointer, _tp_pointer, 256) - + __DEF_PY(Pointer, _Pointer, _tp_pointer) inline _Pointer& PyPointer_AS_C(const PyVar& obj) { if(!obj->isType(_tp_pointer)) typeError("expected an l-value"); return std::get<_Pointer>(obj->_native); } + __DEF_PY_AS_C(Int, _Int, _tp_int) + inline PyVar PyInt(_Int value) { + if(value >= -5 && value <= 256) return _smallIntegers[value + 5]; + return newObject(_tp_int, value); + } + + DEF_NATIVE(Float, _Float, _tp_float) DEF_NATIVE(Str, _Str, _tp_str) DEF_NATIVE(List, PyVarList, _tp_list) DEF_NATIVE(Tuple, PyVarList, _tp_tuple) @@ -1116,7 +1100,7 @@ class ThreadedVM : public VM { void __deleteThread(){ if(_thread != nullptr){ if(_state == THREAD_RUNNING || _state == THREAD_SUSPENDED){ - UNREACHABLE(); + keyboardInterrupt(); } _thread->join(); delete _thread;