This commit is contained in:
blueloveTH 2024-05-04 17:51:09 +08:00
parent 634ad16d45
commit a5800f2bd6
8 changed files with 39 additions and 30 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -195,7 +195,7 @@ namespace pkpy{
} }
PyObject* VM::new_type_object(PyObject* mod, StrName name, Type base, bool subclass_enabled){ 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]; const PyTypeInfo& base_info = _all_types[base];
if(!base_info.subclass_enabled){ if(!base_info.subclass_enabled){
Str error = _S("type ", base_info.name.escape(), " is not `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 #endif
void VM::__init_builtin_types(){ 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(0)), Type(-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(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); PyObject* obj = new_type_object(nullptr, name, base, subclass_enabled);
return PK_OBJ_GET(Type, obj); 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_bound_method != _new_type("bound_method")) exit(-3);
if(tp_super != _new_type("super")) 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_bytes != _new_type("bytes")) exit(-3);
if(tp_mappingproxy != _new_type("mappingproxy")) 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_property != _new_type("property")) exit(-3);
if(tp_star_wrapper != _new_type("_star_wrapper")) exit(-3); if(tp_star_wrapper != _new_type("_star_wrapper")) exit(-3);