ソースを参照

add some std::move

up

Update vm.h
blueloveTH 3 年 前
コミット
fdd1bdb4e6
4 ファイル変更123 行追加21 行削除
  1. 6 1
      src/codeobject.h
  2. 2 1
      src/obj.h
  3. 95 0
      src/shared_ptr.h
  4. 20 19
      src/vm.h

+ 6 - 1
src/codeobject.h

@@ -169,6 +169,11 @@ public:
         return __deref_pointer(vm, s_data.back());
     }
 
+    inline PyVar& __top(){
+        if(s_data.empty()) throw std::runtime_error("s_data.empty() is true");
+        return s_data.back();
+    }
+
     inline PyVar __topValueN(VM* vm, int n=-1){
         return __deref_pointer(vm, s_data[s_data.size() + n]);
     }
@@ -219,7 +224,7 @@ public:
 
     PyVarList __popNReversed(int n){
         PyVarList v(n);
-        for(int i=n-1; i>=0; i--) v[i] = __pop();
+        for(int i=n-1; i>=0; i--) v[i] = std::move(__pop());
         return v;
     }
 };

+ 2 - 1
src/obj.h

@@ -106,5 +106,6 @@ struct PyObject {
         return _type->getName();
     }
 
-    PyObject(_Value val): _native(val) {}
+    PyObject(const _Value& val): _native(val) {}
+    PyObject(_Value&& val): _native(std::move(val)) {}
 };

+ 95 - 0
src/shared_ptr.h

@@ -0,0 +1,95 @@
+#pragma once
+
+#include "__stl__.h"
+
+// sooo slow! do not use this
+namespace pkpy{
+    template <typename T>
+    class shared_ptr {
+        int* count;
+        T* ptr;
+        const std::function<void(T*)>* deleter = nullptr;
+
+    void _delete(){
+        delete count;
+        if(deleter != nullptr) deleter->operator()(ptr);
+        else delete ptr;
+    }
+
+    public:
+        shared_ptr() : count(nullptr), ptr(nullptr) {}
+        shared_ptr(T* ptr) : count(new int(1)), ptr(ptr) {}
+        shared_ptr(T* ptr, const std::function<void(T*)>*) : count(new int(1)), ptr(ptr), deleter(deleter) {}
+        shared_ptr(const shared_ptr& other) : count(other.count), ptr(other.ptr) {
+            if (count) {
+                ++(*count);
+            }
+        }
+        shared_ptr(shared_ptr&& other) : count(other.count), ptr(other.ptr) {
+            other.count = nullptr;
+            other.ptr = nullptr;
+        }
+        ~shared_ptr() {
+            if (count && --(*count) == 0) _delete();
+        }
+
+        bool operator==(const shared_ptr& other) const {
+            return ptr == other.ptr;
+        }
+
+        bool operator!=(const shared_ptr& other) const {
+            return ptr != other.ptr;
+        }
+
+        bool operator==(std::nullptr_t) const {
+            return ptr == nullptr;
+        }
+
+        bool operator!=(std::nullptr_t) const {
+            return ptr != nullptr;
+        }
+
+        shared_ptr& operator=(const shared_ptr& other) {
+            if (this != &other) {
+                if (count && --(*count) == 0) _delete();
+                count = other.count;
+                ptr = other.ptr;
+                if (count) {
+                    ++(*count);
+                }
+            }
+            return *this;
+        }
+        shared_ptr& operator=(shared_ptr&& other) {
+            if (this != &other) {
+                if (count && --(*count) == 0) _delete();
+                count = other.count;
+                ptr = other.ptr;
+                other.count = nullptr;
+                other.ptr = nullptr;
+            }
+            return *this;
+        }
+
+        T& operator*() const {
+            return *ptr;
+        }
+        T* operator->() const {
+            return ptr;
+        }
+        T* get() const {
+            return ptr;
+        }
+        int use_count() const {
+            return count ? *count : 0;
+        }
+        explicit operator bool() const {
+            return ptr != nullptr;
+        }
+    };
+
+    template <typename T, typename... Args>
+    shared_ptr<T> make_shared(Args&&... args) {
+        return shared_ptr<T>(new T(std::forward<Args>(args)...));
+    }
+};

+ 20 - 19
src/vm.h

@@ -25,11 +25,11 @@
         PyObject* _raw = nullptr;                   \
         if(_pool##name.size() > 0) {                \
             _raw = _pool##name.back();              \
-            _raw->_native = _native;                \
+            _raw->_native = std::move(_native);     \
             _pool##name.pop_back();                 \
         }else{                                      \
             __checkType(ptype, _tp_type);           \
-            _raw = new PyObject(_native);           \
+            _raw = new PyObject(std::move(_native));\
             _raw->setType(ptype);                   \
         }                                           \
         return PyVar(_raw, [this](PyObject* p){     \
@@ -82,11 +82,11 @@ private:
             } break;
             case OP_STORE_PTR: {
                 PyVar obj = frame->popValue(this);
-                _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: {
-                _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:
@@ -188,7 +188,7 @@ private:
                 {
                     PyVar rhs = frame->popValue(this);
                     PyVar lhs = frame->popValue(this);
-                    bool ret_c = PyBool_AS_C(call(rhs, __contains__, {lhs}));
+                    bool ret_c = PyBool_AS_C(call(std::move(rhs), __contains__, {std::move(lhs)}));
                     if(byte.arg == 1) ret_c = !ret_c;
                     frame->push(PyBool(ret_c));
                 } break;
@@ -200,7 +200,7 @@ private:
             case OP_UNARY_NOT:
                 {
                     PyVar obj = frame->popValue(this);
-                    PyVar obj_bool = asBool(obj);
+                    const PyVar& obj_bool = asBool(obj);
                     frame->push(PyBool(!PyBool_AS_C(obj_bool)));
                 } break;
             case OP_POP_JUMP_IF_FALSE:
@@ -260,8 +260,8 @@ private:
                     PyVarOrNull iter_fn = getAttr(obj, __iter__, false);
                     if(iter_fn != nullptr){
                         PyVar tmp = call(iter_fn, {obj});
-                        PyIter_AS_C(tmp)->var = PyPointer_AS_C(frame->__pop());
-                        frame->push(tmp);
+                        PyIter_AS_C(tmp)->var = std::move(PyPointer_AS_C(frame->__pop()));
+                        frame->push(std::move(tmp));
                     }else{
                         typeError("'" + obj->getTypeName() + "' object is not iterable");
                     }
@@ -269,8 +269,8 @@ private:
             case OP_FOR_ITER:
                 {
                     frame->__reportForIter();
-                    const PyVar& iter = frame->topValue(this);
-                    auto& it = PyIter_AS_C(iter);
+                    // __top() must be PyIter, so no need to __deref()
+                    auto& it = PyIter_AS_C(frame->__top());
                     if(it->hasNext()){
                         it->var->set(this, frame, it->next());
                     }
@@ -368,20 +368,20 @@ public:
         return call(obj, __json__, {});
     }
 
-    PyVar asBool(const PyVar& obj){
+    const PyVar& asBool(const PyVar& obj){
         if(obj == None) return False;
         if(obj->_type == _tp_bool) return obj;
         if(obj->_type == _tp_int) return PyBool(PyInt_AS_C(obj) != 0);
         if(obj->_type == _tp_float) return PyBool(PyFloat_AS_C(obj) != 0.0);
         PyVarOrNull len_fn = getAttr(obj, __len__, false);
         if(len_fn != nullptr){
-            PyVar ret = call(len_fn, {});
+            PyVar ret = call(std::move(len_fn), {});
             return PyBool(PyInt_AS_C(ret) > 0);
         }
         return True;
     }
 
-    PyVar fastCall(const PyVar& obj, const _Str& name, PyVarList args){
+    PyVar fastCall(const PyVar& obj, const _Str& name, PyVarList&& args){
         PyObject* cls = obj->_type.get();
         while(cls != None.get()) {
             auto it = cls->attribs.find(name);
@@ -418,7 +418,7 @@ public:
         }
         
         if(callable->isType(_tp_native_function)){
-            auto f = std::get<_CppFunc>(callable->_native);
+            const auto& f = std::get<_CppFunc>(callable->_native);
             return f(this, args);
         } else if(callable->isType(_tp_function)){
             const _Func& fn = PyFunction_AS_C(callable);
@@ -664,8 +664,9 @@ public:
     DEF_NATIVE(Range, _Range, _tp_range)
     DEF_NATIVE(Slice, _Slice, _tp_slice)
     
-    inline bool PyBool_AS_C(PyVar obj){return obj == True;}
-    inline PyVar PyBool(bool value){return value ? True : False;}
+    // there is only one True/False, so no need to copy them!
+    inline bool PyBool_AS_C(const PyVar& obj){return obj == True;}
+    inline const PyVar& PyBool(bool value){return value ? True : False;}
 
     void initializeBuiltinClasses(){
         _tp_object = std::make_shared<PyObject>((_Int)0);
@@ -821,13 +822,13 @@ PyVar NamePointer::get(VM* vm, Frame* frame) const{
 
 void NamePointer::set(VM* vm, Frame* frame, PyVar val) const{
     switch(scope) {
-        case NAME_LOCAL: frame->f_locals[name] = val; break;
+        case NAME_LOCAL: frame->f_locals[name] = std::move(val); break;
         case NAME_GLOBAL:
         {
             if(frame->f_locals.count(name) > 0){
-                frame->f_locals[name] = val;
+                frame->f_locals[name] = std::move(val);
             }else{
-                frame->f_globals()[name] = val;
+                frame->f_globals()[name] = std::move(val);
             }
         } break;
         default: UNREACHABLE();