blueloveTH před 3 roky
rodič
revize
a7751461c9
4 změnil soubory, kde provedl 61 přidání a 60 odebrání
  1. 11 11
      src/obj.h
  2. 14 9
      src/pointer.h
  3. 1 0
      src/safestl.h
  4. 35 40
      src/vm.h

+ 11 - 11
src/obj.h

@@ -10,7 +10,6 @@ struct BasePointer;
 class VM;
 class Frame;
 
-typedef pkpy::shared_ptr<const BasePointer> _Pointer;
 typedef PyVar (*_CppFunc)(VM*, const pkpy::ArgList&);
 typedef pkpy::shared_ptr<CodeObject> _Code;
 
@@ -60,7 +59,7 @@ protected:
 public:
     virtual PyVar next() = 0;
     virtual bool hasNext() = 0;
-    _Pointer var;
+    VarRef var;
     BaseIterator(VM* vm, PyVar _ref) : vm(vm), _ref(_ref) {}
     virtual ~BaseIterator() = default;
 };
@@ -69,10 +68,14 @@ typedef pkpy::shared_ptr<Function> _Func;
 typedef pkpy::shared_ptr<BaseIterator> _Iterator;
 
 struct PyObject {
-    PyVarDict attribs;
+protected:
+    void* _value;
+public:
     PyVar _type;
+    PyVarDict attribs;
 
     inline bool isType(const PyVar& type){ return this->_type == type; }
+    inline void* value(){ return _value; }
 
     // currently __name__ is only used for 'type'
     PyVar _typeName(){ return _type->attribs[__name__]; }
@@ -80,17 +83,14 @@ struct PyObject {
 
 template <typename T>
 struct Py_ : PyObject {
-    T _value;
+    T _valueT;
 
-    Py_(const T& val, const PyVar& type) {
-        _value = val;
-        _type = type;
-    }
-    Py_(T&& val, const PyVar& type) {
-        _value = std::move(val);
+    Py_(T val, const PyVar& type) {
+        _valueT = val;
+        _value = &_valueT;
         _type = type;
     }
 };
 
-#define UNION_GET(T, obj) (((Py_<T>*)((obj).get()))->_value)
+#define UNION_GET(T, obj) (((Py_<T>*)((obj).get()))->_valueT)
 #define UNION_TP_NAME(obj) UNION_GET(_Str, (obj)->_typeName())

+ 14 - 9
src/pointer.h

@@ -18,9 +18,10 @@ enum NameScope {
 };
 
 struct NamePointer : BasePointer {
-    const _Str name;
-    const NameScope scope;
-    NamePointer(const _Str& name, NameScope scope) : name(name), scope(scope) {}
+    _Str name;
+    NameScope scope;
+    NamePointer(_Str name, NameScope scope) : name(name), scope(scope) {}
+    NamePointer(){}
 
     bool operator==(const NamePointer& other) const {
         return name == other.name && scope == other.scope;
@@ -35,6 +36,7 @@ struct AttrPointer : BasePointer {
     mutable PyVar obj;
     const NamePointer* attr;
     AttrPointer(PyVar obj, const NamePointer* attr) : obj(obj), attr(attr) {}
+    AttrPointer(){}
 
     PyVar get(VM* vm, Frame* frame) const;
     void set(VM* vm, Frame* frame, PyVar val) const;
@@ -43,8 +45,9 @@ struct AttrPointer : BasePointer {
 
 struct IndexPointer : BasePointer {
     mutable PyVar obj;
-    const PyVar index;
+    PyVar index;
     IndexPointer(PyVar obj, PyVar index) : obj(obj), index(index) {}
+    IndexPointer(){}
 
     PyVar get(VM* vm, Frame* frame) const;
     void set(VM* vm, Frame* frame, PyVar val) const;
@@ -52,9 +55,10 @@ struct IndexPointer : BasePointer {
 };
 
 struct CompoundPointer : BasePointer {
-    const std::vector<_Pointer> pointers;
-    CompoundPointer(const std::vector<_Pointer>& pointers) : pointers(pointers) {}
-    CompoundPointer(std::vector<_Pointer>&& pointers) : pointers(pointers) {}
+    PyVarList varRefs;
+    CompoundPointer(const PyVarList& varRefs) : varRefs(varRefs) {}
+    CompoundPointer(PyVarList&& varRefs) : varRefs(std::move(varRefs)) {}
+    CompoundPointer(){}
 
     PyVar get(VM* vm, Frame* frame) const;
     void set(VM* vm, Frame* frame, PyVar val) const;
@@ -62,9 +66,10 @@ struct CompoundPointer : BasePointer {
 };
 
 struct UserPointer : BasePointer {
-    const _Pointer p;
+    VarRef p;
     uint64_t f_id;
-    UserPointer(_Pointer p, uint64_t f_id) : p(p), f_id(f_id) {}
+    UserPointer(VarRef p, uint64_t f_id) : p(p), f_id(f_id) {}
+    UserPointer() {}
 
     PyVar get(VM* vm, Frame* frame) const;
     void set(VM* vm, Frame* frame, PyVar val) const;

+ 1 - 0
src/safestl.h

@@ -7,6 +7,7 @@
 struct PyObject;
 typedef pkpy::shared_ptr<PyObject> PyVar;
 typedef PyVar PyVarOrNull;
+typedef PyVar VarRef;
 
 class PyVarList: public std::vector<PyVar> {
     PyVar& at(size_t) = delete;

+ 35 - 40
src/vm.h

@@ -19,7 +19,6 @@
     __DEF_PY(type, ctype, ptype)                                \
     __DEF_PY_AS_C(type, ctype, ptype)
 
-typedef void(*PrintFn)(const VM*, const char*);
 
 class VM {
     std::atomic<bool> _stopFlag = false;
@@ -55,9 +54,7 @@ protected:
                 frame->push(obj);
             } break;
             case OP_LOAD_NAME_PTR: {
-                frame->push(PyPointer(
-                    pkpy::make_shared<const BasePointer, NamePointer>(frame->code->co_names[byte.arg])
-                ));
+                frame->push(PyPointer(NamePointer(frame->code->co_names[byte.arg])));
             } break;
             case OP_STORE_NAME_PTR: {
                 const auto& p = frame->code->co_names[byte.arg];
@@ -66,33 +63,28 @@ protected:
             case OP_BUILD_ATTR_PTR: {
                 const auto& attr = frame->code->co_names[byte.arg];
                 PyVar obj = frame->popValue(this);
-                frame->push(PyPointer(
-                    pkpy::make_shared<const BasePointer, AttrPointer>(obj, &attr)
-                ));
+                frame->push(PyPointer(AttrPointer(obj, &attr)));
             } break;
             case OP_BUILD_ATTR_PTR_PTR: {
                 const auto& attr = frame->code->co_names[byte.arg];
                 PyVar obj = frame->popValue(this);
                 __checkType(obj, _tp_user_pointer);
-                const _Pointer& p = UNION_GET(_Pointer, obj);
-                frame->push(PyPointer(
-                    pkpy::make_shared<const BasePointer, AttrPointer>(p->get(this, frame), &attr)
-                ));
+                const VarRef& var = UNION_GET(VarRef, obj);
+                auto p = PyPointer_AS_C(var);
+                frame->push(PyPointer(AttrPointer(p->get(this, frame), &attr)));
             } break;
             case OP_BUILD_INDEX_PTR: {
                 PyVar index = frame->popValue(this);
                 PyVar obj = frame->popValue(this);
-                frame->push(PyPointer(
-                    pkpy::make_shared<const BasePointer, IndexPointer>(obj, index)
-                ));
+                frame->push(PyPointer(IndexPointer(obj, index)));
             } break;
             case OP_STORE_PTR: {
                 PyVar obj = frame->popValue(this);
-                const _Pointer p = PyPointer_AS_C(frame->__pop());
+                auto 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());
+                auto p = PyPointer_AS_C(frame->__pop());
                 p->del(this, frame);
             } break;
             case OP_BUILD_SMART_TUPLE:
@@ -111,12 +103,7 @@ protected:
                     }
                 }
                 if(done) break;
-                std::vector<_Pointer> pointers(items.size());
-                for(int i=0; i<items.size(); i++)
-                    pointers[i] = PyPointer_AS_C(items[i]);
-                frame->push(PyPointer(
-                    pkpy::make_shared<const BasePointer, CompoundPointer>(std::move(pointers))
-                ));
+                frame->push(PyPointer(CompoundPointer(items.toList())));
             } break;
             case OP_BUILD_STRING:
             {
@@ -212,10 +199,11 @@ protected:
             case OP_UNARY_REF:
                 {
                     // _pointer to pointer
-                    const _Pointer p = PyPointer_AS_C(frame->__pop());
+                    VarRef obj = frame->__pop();
+                    __checkType(obj, _tp_pointer);
                     frame->push(newObject(
                         _tp_user_pointer,
-                        pkpy::make_shared<const BasePointer, UserPointer>(p, frame->id)
+                        PyPointer(UserPointer(obj, frame->id))
                     ));
                 } break;
             case OP_UNARY_DEREF:
@@ -223,7 +211,7 @@ protected:
                     // pointer to _pointer
                     PyVar obj = frame->popValue(this);
                     __checkType(obj, _tp_user_pointer);
-                    frame->push(PyPointer(UNION_GET(_Pointer, obj)));
+                    frame->push(UNION_GET(VarRef, obj));
                 } break;
             case OP_POP_JUMP_IF_FALSE:
                 if(!PyBool_AS_C(asBool(frame->popValue(this)))) frame->jump(byte.arg);
@@ -283,7 +271,9 @@ protected:
                     PyVarOrNull iter_fn = getAttr(obj, __iter__, false);
                     if(iter_fn != nullptr){
                         PyVar tmp = call(iter_fn, {obj});
-                        PyIter_AS_C(tmp)->var = std::move(PyPointer_AS_C(frame->__pop()));
+                        VarRef var = frame->__pop();
+                        __checkType(var, _tp_pointer);
+                        PyIter_AS_C(tmp)->var = var;
                         frame->push(std::move(tmp));
                     }else{
                         typeError("'" + UNION_TP_NAME(obj) + "' object is not iterable");
@@ -295,7 +285,7 @@ protected:
                     // __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());
+                        PyPointer_AS_C(it->var)->set(this, frame, it->next());
                     }
                     else{
                         frame->safeJump(byte.arg);
@@ -768,11 +758,16 @@ public:
     PyVar _tp_slice, _tp_range, _tp_module, _tp_pointer;
     PyVar _tp_user_pointer, _tp_super;
 
-    __DEF_PY(Pointer, _Pointer, _tp_pointer)
-    inline _Pointer& PyPointer_AS_C(const PyVar& obj)
+    template<typename P>
+    inline VarRef PyPointer(P value) {
+        static_assert(std::is_base_of<BasePointer, P>::value, "P should derive from BasePointer");
+        return newObject(_tp_pointer, value);
+    }
+
+    inline const BasePointer* PyPointer_AS_C(const PyVar& obj)
     {
         if(!obj->isType(_tp_pointer)) typeError("expected an l-value");
-        return UNION_GET(_Pointer, obj);
+        return (const BasePointer*)(obj->value());
     }
 
     __DEF_PY_AS_C(Int, _Int, _tp_int)
@@ -1021,9 +1016,9 @@ void IndexPointer::del(VM* vm, Frame* frame) const{
 }
 
 PyVar CompoundPointer::get(VM* vm, Frame* frame) const{
-    PyVarList args(pointers.size());
-    for (int i = 0; i < pointers.size(); i++) {
-        args[i] = pointers[i]->get(vm, frame);
+    PyVarList args(varRefs.size());
+    for (int i = 0; i < varRefs.size(); i++) {
+        args[i] = vm->PyPointer_AS_C(varRefs[i])->get(vm, frame);
     }
     return vm->PyTuple(args);
 }
@@ -1033,27 +1028,27 @@ void CompoundPointer::set(VM* vm, Frame* frame, PyVar val) const{
         vm->typeError("only tuple or list can be unpacked");
     }
     const PyVarList& args = UNION_GET(PyVarList, val);
-    if(args.size() > pointers.size()) vm->valueError("too many values to unpack");
-    if(args.size() < pointers.size()) vm->valueError("not enough values to unpack");
-    for (int i = 0; i < pointers.size(); i++) {
-        pointers[i]->set(vm, frame, args[i]);
+    if(args.size() > varRefs.size()) vm->valueError("too many values to unpack");
+    if(args.size() < varRefs.size()) vm->valueError("not enough values to unpack");
+    for (int i = 0; i < varRefs.size(); i++) {
+        vm->PyPointer_AS_C(varRefs[i])->set(vm, frame, args[i]);
     }
 }
 
 void CompoundPointer::del(VM* vm, Frame* frame) const{
-    for (auto& ptr : pointers) ptr->del(vm, frame);
+    for (auto& r : varRefs) vm->PyPointer_AS_C(r)->del(vm, frame);
 }
 
 PyVar UserPointer::get(VM* vm, Frame* frame) const{
     frame = vm->__findFrame(f_id);
     if(frame == nullptr) vm->nullPointerError();
-    return p->get(vm, frame);
+    return vm->PyPointer_AS_C(p)->get(vm, frame);
 }
 
 void UserPointer::set(VM* vm, Frame* frame, PyVar val) const{
     frame = vm->__findFrame(f_id);
     if(frame == nullptr) vm->nullPointerError();
-    p->set(vm, frame, val);
+    vm->PyPointer_AS_C(p)->set(vm, frame, val);
 }
 
 void UserPointer::del(VM* vm, Frame* frame) const{