blueloveTH 3 лет назад
Родитель
Сommit
5f4d47721a
6 измененных файлов с 64 добавлено и 52 удалено
  1. 1 1
      src/main.cpp
  2. 1 2
      src/obj.h
  3. 40 11
      src/pocketpy.h
  4. 1 1
      src/pointer.h
  5. 1 1
      src/repl.h
  6. 20 36
      src/vm.h

+ 1 - 1
src/main.cpp

@@ -94,7 +94,7 @@ int main(int argc, char** argv){
         std::string src((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
 
         ThreadedVM* vm = pkpy_new_tvm(true);
-        _Code code;
+        _Code code = nullptr;
         Timer("Compile time").run([&]{
             code = compile(vm, src.c_str(), filename);
         });

+ 1 - 2
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<const BasePointer> _Pointer;
 typedef PyVar (*_CppFunc)(VM*, const pkpy::ArgList&);

+ 40 - 11
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<typename T>
+class PkExported : public _PkExported{
+    T* _ptr;
+public:
+    template<typename... Args>
+    PkExported(Args&&... args) : _ptr(new T(std::forward<Args>(args)...)){
+        _pkLookupTable.push_back(this);
+    }
+    
+    ~PkExported() override { delete _ptr; }
+    void* get() override { return _ptr; }
+    operator T*() { return _ptr; }
+};
+
+#define pkpy_allocate(T, ...) *(new PkExported<T>(__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

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

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

+ 20 - 36
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<PyObject*> _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<bool> _stopFlag = false;
+    std::vector<PyVar> _smallIntegers;      // [-5, 256]
 protected:
     std::deque< std::unique_ptr<Frame> > 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<UserPointer>(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;