Browse Source

use rtti to get type

blueloveTH 2 years ago
parent
commit
ec044397e6
3 changed files with 8 additions and 5 deletions
  1. 2 4
      include/pocketpy/cffi.h
  2. 2 0
      include/pocketpy/common.h
  3. 4 1
      include/pocketpy/vm.h

+ 2 - 4
include/pocketpy/cffi.h

@@ -7,10 +7,7 @@
 namespace pkpy {
 namespace pkpy {
 
 
 #define PY_CLASS(T, mod, name)                  \
 #define PY_CLASS(T, mod, name)                  \
-    static Type _type(VM* vm) {                 \
-        PK_LOCAL_STATIC const std::pair<StrName, StrName> _path(#mod, #name); \
-        return PK_OBJ_GET(Type, vm->_modules[_path.first]->attr(_path.second)); \
-    }                                                                       \
+    static Type _type(VM* vm) { return vm->_cxx_typeid_map[typeid(T)]; }    \
     static void _check_type(VM* vm, PyObject* val){                         \
     static void _check_type(VM* vm, PyObject* val){                         \
         if(!vm->isinstance(val, T::_type(vm))){                             \
         if(!vm->isinstance(val, T::_type(vm))){                             \
             vm->TypeError("expected '" #mod "." #name "', got " + _type_name(vm, vm->_tp(val)).escape());  \
             vm->TypeError("expected '" #mod "." #name "', got " + _type_name(vm, vm->_tp(val)).escape());  \
@@ -24,6 +21,7 @@ namespace pkpy {
         }                                                                   \
         }                                                                   \
         PyObject* type = vm->new_type_object(mod, #name, base);             \
         PyObject* type = vm->new_type_object(mod, #name, base);             \
         mod->attr().set(#name, type);                                       \
         mod->attr().set(#name, type);                                       \
+        vm->_cxx_typeid_map[typeid(T)] = PK_OBJ_GET(Type, type);            \
         T::_register(vm, mod, type);                                        \
         T::_register(vm, mod, type);                                        \
         return type;                                                        \
         return type;                                                        \
     }                                                                       
     }                                                                       

+ 2 - 0
include/pocketpy/common.h

@@ -18,6 +18,7 @@
 #include <type_traits>
 #include <type_traits>
 #include <random>
 #include <random>
 #include <deque>
 #include <deque>
+#include <typeindex>
 #include <initializer_list>
 #include <initializer_list>
 
 
 #define PK_VERSION				"1.4.2"
 #define PK_VERSION				"1.4.2"
@@ -159,6 +160,7 @@ struct Discarded { };
 
 
 struct Type {
 struct Type {
 	int index;
 	int index;
+	constexpr Type(): index(-1) {}
 	constexpr Type(int index): index(index) {}
 	constexpr Type(int index): index(index) {}
 	bool operator==(Type other) const { return this->index == other.index; }
 	bool operator==(Type other) const { return this->index == other.index; }
 	bool operator!=(Type other) const { return this->index != other.index; }
 	bool operator!=(Type other) const { return this->index != other.index; }

+ 4 - 1
include/pocketpy/vm.h

@@ -141,6 +141,9 @@ public:
     // cached code objects for FSTRING_EVAL
     // cached code objects for FSTRING_EVAL
     std::map<std::string_view, CodeObject_> _cached_codes;
     std::map<std::string_view, CodeObject_> _cached_codes;
 
 
+    // typeid -> Type
+    std::map<std::type_index, Type> _cxx_typeid_map;
+
     void (*_ceval_on_step)(VM*, Frame*, Bytecode bc) = nullptr;
     void (*_ceval_on_step)(VM*, Frame*, Bytecode bc) = nullptr;
 
 
     LineProfiler* _profiler = nullptr;
     LineProfiler* _profiler = nullptr;
@@ -191,7 +194,7 @@ public:
         return _run_top_frame();
         return _run_top_frame();
     }
     }
 
 
-    void _push_varargs(){ }
+    void _push_varargs(){}
     void _push_varargs(PyObject* _0){ PUSH(_0); }
     void _push_varargs(PyObject* _0){ PUSH(_0); }
     void _push_varargs(PyObject* _0, PyObject* _1){ PUSH(_0); PUSH(_1); }
     void _push_varargs(PyObject* _0, PyObject* _1){ PUSH(_0); PUSH(_1); }
     void _push_varargs(PyObject* _0, PyObject* _1, PyObject* _2){ PUSH(_0); PUSH(_1); PUSH(_2); }
     void _push_varargs(PyObject* _0, PyObject* _1, PyObject* _2){ PUSH(_0); PUSH(_1); PUSH(_2); }