blueloveTH 1 year ago
parent
commit
a5800f2bd6
8 changed files with 39 additions and 30 deletions
  1. 1 1
      include/pocketpy/common.h
  2. 22 13
      include/pocketpy/vm.h
  3. 1 1
      src/array2d.cpp
  4. 3 3
      src/cffi.cpp
  5. 1 1
      src/codeobject.cpp
  6. 1 1
      src/collections.cpp
  7. 4 4
      src/linalg.cpp
  8. 6 6
      src/vm.cpp

+ 1 - 1
include/pocketpy/common.h

@@ -99,7 +99,7 @@ struct Discarded { };
 struct Type {
 	int index;
 	constexpr Type(): index(-1) {}
-	constexpr Type(int index): index(index) {}
+	explicit 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; }
 	operator int() const { return this->index; }

+ 22 - 13
include/pocketpy/vm.h

@@ -27,6 +27,7 @@ namespace pkpy{
 #define STACK_VIEW(n)     (s_data.view(n))
 
 typedef PyObject* (*BinaryFuncC)(VM*, PyObject*, PyObject*);
+typedef void (*RegisterFunc)(VM*, PyObject*, PyObject*);
 
 #if PK_ENABLE_PROFILER
 struct NextBreakpoint{
@@ -169,14 +170,14 @@ public:
     unsigned char* (*_import_handler)(const char*, int, int*);
 
     // for quick access
-    static constexpr Type tp_object=0, tp_type=1;
-    static constexpr Type tp_int=kTpIntIndex, tp_float=kTpFloatIndex, tp_bool=4, tp_str=5;
-    static constexpr Type tp_list=6, tp_tuple=7;
-    static constexpr Type tp_slice=8, tp_range=9, tp_module=10;
-    static constexpr Type tp_function=11, tp_native_func=12, tp_bound_method=13;
-    static constexpr Type tp_super=14, tp_exception=15, tp_bytes=16, tp_mappingproxy=17;
-    static constexpr Type tp_dict=18, tp_property=19, tp_star_wrapper=20;
-    static constexpr Type tp_staticmethod=21, tp_classmethod=22;
+    static constexpr Type tp_object=Type(0), tp_type=Type(1);
+    static constexpr Type tp_int=Type(kTpIntIndex), tp_float=Type(kTpFloatIndex), tp_bool=Type(4), tp_str=Type(5);
+    static constexpr Type tp_list=Type(6), tp_tuple=Type(7);
+    static constexpr Type tp_slice=Type(8), tp_range=Type(9), tp_module=Type(10);
+    static constexpr Type tp_function=Type(11), tp_native_func=Type(12), tp_bound_method=Type(13);
+    static constexpr Type tp_super=Type(14), tp_exception=Type(15), tp_bytes=Type(16), tp_mappingproxy=Type(17);
+    static constexpr Type tp_dict=Type(18), tp_property=Type(19), tp_star_wrapper=Type(20);
+    static constexpr Type tp_staticmethod=Type(21), tp_classmethod=Type(22);
 
     const bool enable_os;
     VM(bool enable_os=true);
@@ -353,8 +354,11 @@ public:
     Type _tp_user(){ return _find_type_in_cxx_typeid_map<T>(); }
     template<typename T>
     bool is_user_type(PyObject* obj){ return _tp(obj) == _tp_user<T>(); }
+
+    template<typename T>
+    PyObject* register_user_class(PyObject*, StrName, RegisterFunc, Type base=tp_object, bool subclass_enabled=false);
     template<typename T>
-    PyObject* register_user_class(PyObject* mod, StrName name, bool subclass_enabled=false);
+    PyObject* register_user_class(PyObject*, StrName, Type base=tp_object, bool subclass_enabled=false);
 
     template<typename T, typename ...Args>
     PyObject* new_user_object(Args&&... args){
@@ -413,7 +417,7 @@ inline constexpr bool is_immutable_v = is_integral_v<T> || is_floating_point_v<T
     || std::is_same_v<T, Range> || std::is_same_v<T, Slice>
     || std::is_pointer_v<T> || std::is_enum_v<T>;
 
-template<typename T> constexpr Type _find_type_in_const_cxx_typeid_map(){ return -1; }
+template<typename T> constexpr Type _find_type_in_const_cxx_typeid_map(){ return Type(-1); }
 template<> constexpr Type _find_type_in_const_cxx_typeid_map<Str>(){ return VM::tp_str; }
 template<> constexpr Type _find_type_in_const_cxx_typeid_map<List>(){ return VM::tp_list; }
 template<> constexpr Type _find_type_in_const_cxx_typeid_map<Tuple>(){ return VM::tp_tuple; }
@@ -542,11 +546,11 @@ template<typename __T>
 __T _py_cast(VM* vm, PyObject* obj) { return _py_cast__internal<__T, false>(vm, obj); }
 
 template<typename T>
-PyObject* VM::register_user_class(PyObject* mod, StrName name, bool subclass_enabled){
-    PyObject* type = new_type_object(mod, name, 0, subclass_enabled);
+PyObject* VM::register_user_class(PyObject* mod, StrName name, RegisterFunc _register, Type base, bool subclass_enabled){
+    PyObject* type = new_type_object(mod, name, base, subclass_enabled);
     mod->attr().set(name, type);
     _cxx_typeid_map[typeid(T)] = PK_OBJ_GET(Type, type);
-    T::_register(vm, mod, type);
+    _register(this, mod, type);
     // check if T is trivially constructible
     if constexpr(!std::is_default_constructible_v<T>){
         if(!type->attr().contains(__new__)){
@@ -559,4 +563,9 @@ PyObject* VM::register_user_class(PyObject* mod, StrName name, bool subclass_ena
     return type;
 }
 
+template<typename T>
+PyObject* VM::register_user_class(PyObject* mod, StrName name, Type base, bool subclass_enabled){
+    return register_user_class<T>(mod, name, &T::_register, base, subclass_enabled);
+}
+
 }   // namespace pkpy

+ 1 - 1
src/array2d.cpp

@@ -369,7 +369,7 @@ struct Array2dIter{
 void add_module_array2d(VM* vm){
     PyObject* mod = vm->new_module("array2d");
 
-    vm->register_user_class<Array2d>(mod, "array2d", true);
+    vm->register_user_class<Array2d>(mod, "array2d", VM::tp_object, true);
     vm->register_user_class<Array2dIter>(mod, "_array2d_iter");
 
     vm->bind__iter__(vm->_tp_user<Array2d>(), [](VM* vm, PyObject* _0){

+ 3 - 3
src/cffi.cpp

@@ -161,8 +161,8 @@ void add_module_c(VM* vm){
         return vm->None;
     });
 
-    vm->register_user_class<VoidP>(mod, "void_p", true);
-    vm->register_user_class<Struct>(mod, "struct", true);
+    vm->register_user_class<VoidP>(mod, "void_p", VM::tp_object, true);
+    vm->register_user_class<Struct>(mod, "struct", VM::tp_object, true);
     
     mod->attr().set("NULL", vm->new_user_object<VoidP>(nullptr));
 
@@ -188,7 +188,7 @@ void add_module_c(VM* vm){
     });
 
     PyObject* type;
-    Type type_t = -1;
+    Type type_t;
 
 #define BIND_PRIMITIVE(T, CNAME) \
     vm->bind_func(mod, CNAME "_", 1, [](VM* vm, ArgsView args){         \

+ 1 - 1
src/codeobject.cpp

@@ -25,7 +25,7 @@ namespace pkpy{
     }
 
     struct PySignalObject: PyObject {
-        PySignalObject() : PyObject(0) { gc_enabled = false; }
+        PySignalObject() : PyObject(Type(0)) { gc_enabled = false; }
         void _obj_gc_mark() override {}
     };
 

+ 1 - 1
src/collections.cpp

@@ -541,7 +541,7 @@ namespace pkpy
     void add_module_collections(VM *vm)
     {
         PyObject *mod = vm->new_module("collections");
-        vm->register_user_class<PyDeque>(mod, "deque", true);
+        vm->register_user_class<PyDeque>(mod, "deque", VM::tp_object, true);
         vm->register_user_class<PyDequeIter>(mod, "_deque_iter");
         CodeObject_ code = vm->compile(kPythonLibs_collections, "collections.py", EXEC_MODE);
         vm->_exec(code, mod);

+ 4 - 4
src/linalg.cpp

@@ -541,10 +541,10 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
 void add_module_linalg(VM* vm){
     PyObject* linalg = vm->new_module("linalg");
 
-    vm->register_user_class<Vec2>(linalg, "vec2", true);
-    vm->register_user_class<Vec3>(linalg, "vec3", true);
-    vm->register_user_class<Vec4>(linalg, "vec4", true);
-    vm->register_user_class<Mat3x3>(linalg, "mat3x3", true);
+    vm->register_user_class<Vec2>(linalg, "vec2", VM::tp_object, true);
+    vm->register_user_class<Vec3>(linalg, "vec3", VM::tp_object, true);
+    vm->register_user_class<Vec4>(linalg, "vec4", VM::tp_object, true);
+    vm->register_user_class<Mat3x3>(linalg, "mat3x3", VM::tp_object, true);
 
     PyObject* float_p = vm->_modules["c"]->attr("float_p");
     linalg->attr().set("vec2_p", float_p);

+ 6 - 6
src/vm.cpp

@@ -195,7 +195,7 @@ namespace pkpy{
     }
 
     PyObject* VM::new_type_object(PyObject* mod, StrName name, Type base, bool subclass_enabled){
-        PyObject* obj = heap._new<Type>(tp_type, _all_types.size());
+        PyObject* obj = heap._new<Type>(tp_type, Type(_all_types.size()));
         const PyTypeInfo& base_info = _all_types[base];
         if(!base_info.subclass_enabled){
             Str error = _S("type ", base_info.name.escape(), " is not `subclass_enabled`");
@@ -735,10 +735,10 @@ void VM::__log_s_data(const char* title) {
 #endif
 
 void VM::__init_builtin_types(){
-    _all_types.push_back({heap._new<Type>(Type(1), Type(0)), -1, nullptr, "object", true});
-    _all_types.push_back({heap._new<Type>(Type(1), Type(1)), 0, nullptr, "type", false});
+    _all_types.push_back({heap._new<Type>(Type(1), Type(0)), Type(-1), nullptr, "object", true});
+    _all_types.push_back({heap._new<Type>(Type(1), Type(1)), Type(0), nullptr, "type", false});
 
-    auto _new_type = [this](const char* name, Type base=0, bool subclass_enabled=false){
+    auto _new_type = [this](const char* name, Type base=Type(0), bool subclass_enabled=false){
         PyObject* obj = new_type_object(nullptr, name, base, subclass_enabled);
         return PK_OBJ_GET(Type, obj);
     };
@@ -759,10 +759,10 @@ void VM::__init_builtin_types(){
     if(tp_bound_method != _new_type("bound_method")) exit(-3);
 
     if(tp_super != _new_type("super")) exit(-3);
-    if(tp_exception != _new_type("Exception", 0, true)) exit(-3);
+    if(tp_exception != _new_type("Exception", Type(0), true)) exit(-3);
     if(tp_bytes != _new_type("bytes")) exit(-3);
     if(tp_mappingproxy != _new_type("mappingproxy")) exit(-3);
-    if(tp_dict != _new_type("dict", 0, true)) exit(-3);  // dict can be subclassed
+    if(tp_dict != _new_type("dict", Type(0), true)) exit(-3);  // dict can be subclassed
     if(tp_property != _new_type("property")) exit(-3);
     if(tp_star_wrapper != _new_type("_star_wrapper")) exit(-3);