This commit is contained in:
blueloveTH 2024-05-13 01:59:38 +08:00
parent 529c23043c
commit cef275f900
10 changed files with 78 additions and 74 deletions

View File

@ -7,7 +7,7 @@ namespace pkpy {
#define PY_CLASS(T, mod, name) \ #define PY_CLASS(T, mod, name) \
[[deprecated]] static Type _type(VM* vm) { return vm->_cxx_typeid_map[typeid(T)]; } \ [[deprecated]] static Type _type(VM* vm) { return vm->_cxx_typeid_map[typeid(T)]; } \
[[deprecated]] static PyVar register_class(VM* vm, PyVar mod, Type base=Type(0)) { \ [[deprecated]] static PyVar register_class(VM* vm, PyVar mod, Type base=VM::tp_object) { \
return vm->register_user_class<T>(mod, #name, base); \ return vm->register_user_class<T>(mod, #name, base); \
} }

View File

@ -98,11 +98,11 @@ struct Discarded { };
struct Type { struct Type {
int16_t index; int16_t index;
constexpr Type(): index(-1) {} constexpr Type(): index(0) {}
explicit 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; }
explicit operator bool() const { return index != -1; } constexpr operator int() const { return index; }
}; };
#define PK_LAMBDA(x) ([](VM* vm, ArgsView args) { return x; }) #define PK_LAMBDA(x) ([](VM* vm, ArgsView args) { return x; })
@ -178,7 +178,11 @@ struct PyVar final{
char _bytes[12]; char _bytes[12];
// uninitialized // uninitialized
#if PK_DEBUG_EXTRA_CHECK
PyVar(): type() { } PyVar(): type() { }
#else
PyVar() = default;
#endif
// zero initialized // zero initialized
PyVar(std::nullptr_t): type(), is_sso(false), flags(0), _bytes{0} { } PyVar(std::nullptr_t): type(), is_sso(false), flags(0), _bytes{0} { }
// PyObject* initialized (is_sso = false) // PyObject* initialized (is_sso = false)

View File

@ -33,11 +33,11 @@
/*************** debug settings ***************/ /*************** debug settings ***************/
// Enable this may help you find bugs // Enable this may help you find bugs
#define PK_DEBUG_EXTRA_CHECK 0 #define PK_DEBUG_EXTRA_CHECK 1
// Do not edit the following settings unless you know what you are doing // Do not edit the following settings unless you know what you are doing
#define PK_DEBUG_CEVAL_STEP 0 #define PK_DEBUG_CEVAL_STEP 0
#define PK_DEBUG_MEMORY_POOL 0 #define PK_DEBUG_MEMORY_POOL 1
#define PK_DEBUG_NO_MEMORY_POOL 0 #define PK_DEBUG_NO_MEMORY_POOL 0
#define PK_DEBUG_NO_AUTO_GC 0 #define PK_DEBUG_NO_AUTO_GC 0
#define PK_DEBUG_GC_STATS 0 #define PK_DEBUG_GC_STATS 0

View File

@ -124,8 +124,8 @@ struct PyObject{
} }
}; };
const int kTpIntIndex = 2; const int kTpIntIndex = 3;
const int kTpFloatIndex = 3; const int kTpFloatIndex = 4;
inline bool is_tagged(PyVar p) noexcept { return p.is_sso; } inline bool is_tagged(PyVar p) noexcept { return p.is_sso; }
inline bool is_float(PyVar p) noexcept { return p.type.index == kTpFloatIndex; } inline bool is_float(PyVar p) noexcept { return p.type.index == kTpFloatIndex; }

View File

@ -173,14 +173,14 @@ public:
// function<unsigned char*(const char*, int*)> _import_handler; // function<unsigned char*(const char*, int*)> _import_handler;
// for quick access // for quick access
static constexpr Type tp_object=Type(0), tp_type=Type(1); static constexpr Type tp_object=Type(1), tp_type=Type(2);
static constexpr Type tp_int=Type(kTpIntIndex), tp_float=Type(kTpFloatIndex), tp_bool=Type(4), tp_str=Type(5); static constexpr Type tp_int=Type(kTpIntIndex), tp_float=Type(kTpFloatIndex), tp_bool=Type(5), tp_str=Type(6);
static constexpr Type tp_list=Type(6), tp_tuple=Type(7); static constexpr Type tp_list=Type(7), tp_tuple=Type(8);
static constexpr Type tp_slice=Type(8), tp_range=Type(9), tp_module=Type(10); static constexpr Type tp_slice=Type(9), tp_range=Type(10), tp_module=Type(11);
static constexpr Type tp_function=Type(11), tp_native_func=Type(12), tp_bound_method=Type(13); static constexpr Type tp_function=Type(12), tp_native_func=Type(13), tp_bound_method=Type(14);
static constexpr Type tp_super=Type(14), tp_exception=Type(15), tp_bytes=Type(16), tp_mappingproxy=Type(17); static constexpr Type tp_super=Type(15), tp_exception=Type(16), tp_bytes=Type(17), tp_mappingproxy=Type(18);
static constexpr Type tp_dict=Type(18), tp_property=Type(19), tp_star_wrapper=Type(20); static constexpr Type tp_dict=Type(19), tp_property=Type(20), tp_star_wrapper=Type(21);
static constexpr Type tp_staticmethod=Type(21), tp_classmethod=Type(22); static constexpr Type tp_staticmethod=Type(22), tp_classmethod=Type(23);
const bool enable_os; const bool enable_os;
VM(bool enable_os=true); VM(bool enable_os=true);
@ -366,10 +366,10 @@ public:
void check_compatible_type(PyVar obj, Type type){ if(!isinstance(obj, type)) TypeError(type, _tp(obj)); } void check_compatible_type(PyVar obj, Type type){ if(!isinstance(obj, type)) TypeError(type, _tp(obj)); }
Type _tp(PyVar obj){ return obj.type; } Type _tp(PyVar obj){ return obj.type; }
const PyTypeInfo* _tp_info(PyVar obj) { return &_all_types[_tp(obj).index]; } const PyTypeInfo* _tp_info(PyVar obj) { return &_all_types[_tp(obj)]; }
const PyTypeInfo* _tp_info(Type type) { return &_all_types[type.index]; } const PyTypeInfo* _tp_info(Type type) { return &_all_types[type]; }
PyVar _t(PyVar obj){ return _all_types[_tp(obj).index].obj; } PyVar _t(PyVar obj){ return _all_types[_tp(obj)].obj; }
PyVar _t(Type type){ return _all_types[type.index].obj; } PyVar _t(Type type){ return _all_types[type].obj; }
#endif #endif
#if PK_REGION("User Type Registration") #if PK_REGION("User Type Registration")
@ -445,7 +445,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 Type(-1); } template<typename T> constexpr Type _find_type_in_const_cxx_typeid_map(){ return Type(); }
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; }
@ -488,7 +488,7 @@ PyVar py_var(VM* vm, __T&& value){
return from_void_p(vm, (void*)value); return from_void_p(vm, (void*)value);
}else{ }else{
constexpr Type const_type = _find_type_in_const_cxx_typeid_map<T>(); constexpr Type const_type = _find_type_in_const_cxx_typeid_map<T>();
if constexpr(const_type.index >= 0){ if constexpr(const_type){
return vm->heap.gcnew<T>(const_type, std::forward<__T>(value)); return vm->heap.gcnew<T>(const_type, std::forward<__T>(value));
} }
} }
@ -542,7 +542,7 @@ __T _py_cast__internal(VM* vm, PyVar obj) {
return to_void_p<T>(vm, obj); return to_void_p<T>(vm, obj);
}else{ }else{
constexpr Type const_type = _find_type_in_const_cxx_typeid_map<T>(); constexpr Type const_type = _find_type_in_const_cxx_typeid_map<T>();
if constexpr(const_type.index >= 0){ if constexpr(const_type){
if constexpr(with_check){ if constexpr(with_check){
if constexpr(std::is_same_v<T, Exception>){ if constexpr(std::is_same_v<T, Exception>){
// Exception is `subclass_enabled` // Exception is `subclass_enabled`

View File

@ -898,9 +898,9 @@ __NEXT_STEP:;
StrName _name(byte.arg); StrName _name(byte.arg);
frame->_module->attr().set(_name, __curr_class); frame->_module->attr().set(_name, __curr_class);
// call on_end_subclass // call on_end_subclass
PyTypeInfo* ti = &_all_types[PK_OBJ_GET(Type, __curr_class).index]; PyTypeInfo* ti = &_all_types[PK_OBJ_GET(Type, __curr_class)];
if(ti->base != tp_object){ if(ti->base != tp_object){
PyTypeInfo* base_ti = &_all_types[ti->base.index]; PyTypeInfo* base_ti = &_all_types[ti->base];
if(base_ti->on_end_subclass) base_ti->on_end_subclass(this, ti); if(base_ti->on_end_subclass) base_ti->on_end_subclass(this, ti);
} }
__curr_class = nullptr; __curr_class = nullptr;
@ -924,7 +924,7 @@ __NEXT_STEP:;
PK_ASSERT(__curr_class != nullptr); PK_ASSERT(__curr_class != nullptr);
StrName _name(byte.arg); StrName _name(byte.arg);
Type type = PK_OBJ_GET(Type, __curr_class); Type type = PK_OBJ_GET(Type, __curr_class);
_all_types[type.index].annotated_fields.push_back(_name); _all_types[type].annotated_fields.push_back(_name);
} DISPATCH() } DISPATCH()
/*****************************************/ /*****************************************/
case OP_WITH_ENTER: case OP_WITH_ENTER:

View File

@ -13,7 +13,7 @@ static void patch__init__(VM* vm, Type cls){
}); });
Type cls = vm->_tp(self); Type cls = vm->_tp(self);
const PyTypeInfo* cls_info = &vm->_all_types[cls.index]; const PyTypeInfo* cls_info = &vm->_all_types[cls];
NameDict& cls_d = cls_info->obj->attr(); NameDict& cls_d = cls_info->obj->attr();
const auto& fields = cls_info->annotated_fields; const auto& fields = cls_info->annotated_fields;
@ -46,7 +46,7 @@ static void patch__init__(VM* vm, Type cls){
static void patch__repr__(VM* vm, Type cls){ static void patch__repr__(VM* vm, Type cls){
vm->bind__repr__(cls, [](VM* vm, PyVar _0) -> Str{ vm->bind__repr__(cls, [](VM* vm, PyVar _0) -> Str{
const PyTypeInfo* cls_info = &vm->_all_types[vm->_tp(_0).index]; const PyTypeInfo* cls_info = &vm->_all_types[vm->_tp(_0)];
const auto& fields = cls_info->annotated_fields; const auto& fields = cls_info->annotated_fields;
const NameDict& obj_d = _0->attr(); const NameDict& obj_d = _0->attr();
SStream ss; SStream ss;
@ -65,7 +65,7 @@ static void patch__repr__(VM* vm, Type cls){
static void patch__eq__(VM* vm, Type cls){ static void patch__eq__(VM* vm, Type cls){
vm->bind__eq__(cls, [](VM* vm, PyVar _0, PyVar _1){ vm->bind__eq__(cls, [](VM* vm, PyVar _0, PyVar _1){
if(vm->_tp(_0) != vm->_tp(_1)) return vm->NotImplemented; if(vm->_tp(_0) != vm->_tp(_1)) return vm->NotImplemented;
const PyTypeInfo* cls_info = &vm->_all_types[vm->_tp(_0).index]; const PyTypeInfo* cls_info = &vm->_all_types[vm->_tp(_0)];
const auto& fields = cls_info->annotated_fields; const auto& fields = cls_info->annotated_fields;
for(StrName field: fields){ for(StrName field: fields){
PyVar lhs = _0->attr(field); PyVar lhs = _0->attr(field);
@ -88,7 +88,7 @@ void add_module_dataclasses(VM* vm){
if(!cls_d.contains(__repr__)) patch__repr__(vm, cls); if(!cls_d.contains(__repr__)) patch__repr__(vm, cls);
if(!cls_d.contains(__eq__)) patch__eq__(vm, cls); if(!cls_d.contains(__eq__)) patch__eq__(vm, cls);
const auto& fields = vm->_all_types[cls.index].annotated_fields; const auto& fields = vm->_all_types[cls].annotated_fields;
bool has_default = false; bool has_default = false;
for(StrName field: fields){ for(StrName field: fields){
if(cls_d.contains(field)){ if(cls_d.contains(field)){

View File

@ -239,7 +239,7 @@ void add_module_enum(VM* vm){
CodeObject_ code = vm->compile(kPythonLibs__enum, "enum.py", EXEC_MODE); CodeObject_ code = vm->compile(kPythonLibs__enum, "enum.py", EXEC_MODE);
vm->_exec(code, mod); vm->_exec(code, mod);
PyVar Enum = mod->attr("Enum"); PyVar Enum = mod->attr("Enum");
vm->_all_types[PK_OBJ_GET(Type, Enum).index].on_end_subclass = \ vm->_all_types[PK_OBJ_GET(Type, Enum)].on_end_subclass = \
[](VM* vm, PyTypeInfo* new_ti){ [](VM* vm, PyTypeInfo* new_ti){
new_ti->subclass_enabled = false; // Enum class cannot be subclassed twice new_ti->subclass_enabled = false; // Enum class cannot be subclassed twice
NameDict& attr = new_ti->obj->attr(); NameDict& attr = new_ti->obj->attr();

View File

@ -104,7 +104,7 @@ void __init_builtins(VM* _vm) {
StrName _1 = _type_name(vm, type); StrName _1 = _type_name(vm, type);
vm->TypeError("super(): " + _0.escape() + " is not an instance of " + _1.escape()); vm->TypeError("super(): " + _0.escape() + " is not an instance of " + _1.escape());
} }
return vm->heap.gcnew<Super>(vm->tp_super, self_arg, vm->_all_types[type.index].base); return vm->heap.gcnew<Super>(vm->tp_super, self_arg, vm->_all_types[type].base);
}); });
_vm->bind_func(_vm->builtins, "staticmethod", 1, [](VM* vm, ArgsView args) { _vm->bind_func(_vm->builtins, "staticmethod", 1, [](VM* vm, ArgsView args) {
@ -406,14 +406,14 @@ void __init_builtins(VM* _vm) {
if(args.size() == 1+0) return VAR(0); if(args.size() == 1+0) return VAR(0);
// 1 arg // 1 arg
if(args.size() == 1+1){ if(args.size() == 1+1){
switch(vm->_tp(args[1]).index){ switch(vm->_tp(args[1])){
case VM::tp_float.index: case VM::tp_float:
return VAR((i64)_CAST(f64, args[1])); return VAR((i64)_CAST(f64, args[1]));
case VM::tp_int.index: case VM::tp_int:
return args[1]; return args[1];
case VM::tp_bool.index: case VM::tp_bool:
return VAR(args[1]==vm->True ? 1 : 0); return VAR(args[1]==vm->True ? 1 : 0);
case VM::tp_str.index: case VM::tp_str:
break; break;
default: default:
vm->TypeError("invalid arguments for int()"); vm->TypeError("invalid arguments for int()");
@ -483,14 +483,14 @@ void __init_builtins(VM* _vm) {
if(args.size() == 1+0) return VAR(0.0); if(args.size() == 1+0) return VAR(0.0);
if(args.size() > 1+1) vm->TypeError("float() takes at most 1 argument"); if(args.size() > 1+1) vm->TypeError("float() takes at most 1 argument");
// 1 arg // 1 arg
switch(vm->_tp(args[1]).index){ switch(vm->_tp(args[1])){
case VM::tp_int.index: case VM::tp_int:
return VAR((f64)CAST(i64, args[1])); return VAR((f64)CAST(i64, args[1]));
case VM::tp_float.index: case VM::tp_float:
return args[1]; return args[1];
case VM::tp_bool.index: case VM::tp_bool:
return VAR(args[1]==vm->True ? 1.0 : 0.0); return VAR(args[1]==vm->True ? 1.0 : 0.0);
case VM::tp_str.index: case VM::tp_str:
break; break;
default: default:
vm->TypeError("invalid arguments for float()"); vm->TypeError("invalid arguments for float()");
@ -1502,7 +1502,7 @@ void VM::__post_init_builtin_types(){
bind_func(tp_module, __new__, -1, PK_ACTION(vm->NotImplementedError())); bind_func(tp_module, __new__, -1, PK_ACTION(vm->NotImplementedError()));
_all_types[tp_module.index].m__getattr__ = [](VM* vm, PyVar obj, StrName name) -> PyVar{ _all_types[tp_module].m__getattr__ = [](VM* vm, PyVar obj, StrName name) -> PyVar{
const Str& path = CAST(Str&, obj->attr(__path__)); const Str& path = CAST(Str&, obj->attr(__path__));
return vm->py_import(_S(path, ".", name.sv()), false); return vm->py_import(_S(path, ".", name.sv()), false);
}; };
@ -1522,22 +1522,22 @@ void VM::__post_init_builtin_types(){
bind__repr__(tp_type, [](VM* vm, PyVar self) -> Str{ bind__repr__(tp_type, [](VM* vm, PyVar self) -> Str{
SStream ss; SStream ss;
const PyTypeInfo& info = vm->_all_types[PK_OBJ_GET(Type, self).index]; const PyTypeInfo& info = vm->_all_types[PK_OBJ_GET(Type, self)];
ss << "<class '" << info.name << "'>"; ss << "<class '" << info.name << "'>";
return ss.str(); return ss.str();
}); });
bind_property(_t(tp_object), "__class__", PK_LAMBDA(vm->_t(args[0]))); bind_property(_t(tp_object), "__class__", PK_LAMBDA(vm->_t(args[0])));
bind_property(_t(tp_type), "__base__", [](VM* vm, ArgsView args){ bind_property(_t(tp_type), "__base__", [](VM* vm, ArgsView args){
const PyTypeInfo& info = vm->_all_types[PK_OBJ_GET(Type, args[0]).index]; const PyTypeInfo& info = vm->_all_types[PK_OBJ_GET(Type, args[0])];
return info.base.index == -1 ? vm->None : vm->_all_types[info.base.index].obj; return info.base.index == -1 ? vm->None : vm->_all_types[info.base].obj;
}); });
bind_property(_t(tp_type), "__name__", [](VM* vm, ArgsView args){ bind_property(_t(tp_type), "__name__", [](VM* vm, ArgsView args){
const PyTypeInfo& info = vm->_all_types[PK_OBJ_GET(Type, args[0]).index]; const PyTypeInfo& info = vm->_all_types[PK_OBJ_GET(Type, args[0])];
return VAR(info.name.sv()); return VAR(info.name.sv());
}); });
bind_property(_t(tp_type), "__module__", [](VM* vm, ArgsView args){ bind_property(_t(tp_type), "__module__", [](VM* vm, ArgsView args){
const PyTypeInfo& info = vm->_all_types[PK_OBJ_GET(Type, args[0]).index]; const PyTypeInfo& info = vm->_all_types[PK_OBJ_GET(Type, args[0])];
if(info.mod == nullptr) return vm->None; if(info.mod == nullptr) return vm->None;
return info.mod; return info.mod;
}); });

View File

@ -148,7 +148,7 @@ namespace pkpy{
do{ do{
val = _t(cls)->attr().try_get(name); val = _t(cls)->attr().try_get(name);
if(val != nullptr) return val; if(val != nullptr) return val;
cls = _all_types[cls.index].base; cls = _all_types[cls].base;
if(cls.index == -1) break; if(cls.index == -1) break;
}while(true); }while(true);
return nullptr; return nullptr;
@ -161,7 +161,7 @@ namespace pkpy{
bool VM::issubclass(Type cls, Type base){ bool VM::issubclass(Type cls, Type base){
do{ do{
if(cls == base) return true; if(cls == base) return true;
Type next = _all_types[cls.index].base; Type next = _all_types[cls].base;
if(next.index == -1) break; if(next.index == -1) break;
cls = next; cls = next;
}while(true); }while(true);
@ -206,8 +206,8 @@ namespace pkpy{
} }
PyVar VM::new_type_object(PyVar mod, StrName name, Type base, bool subclass_enabled){ PyVar VM::new_type_object(PyVar mod, StrName name, Type base, bool subclass_enabled){
PyVar obj = heap._new<Type>(tp_type, Type(_all_types.size())); PyVar obj = heap._new<Type>(tp_type, Type(_all_types.size()+1));
const PyTypeInfo& base_info = _all_types[base.index]; 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`");
throw std::runtime_error(error.c_str()); throw std::runtime_error(error.c_str());
@ -501,7 +501,7 @@ i64 VM::py_hash(PyVar obj){
return CAST(i64, ret); return CAST(i64, ret);
} }
// if it is trivial `object`, return PK_BITS // if it is trivial `object`, return PK_BITS
if(ti == &_all_types[tp_object.index]) return obj.hash(); if(ti == &_all_types[tp_object]) return obj.hash();
// otherwise, we check if it has a custom __eq__ other than object.__eq__ // otherwise, we check if it has a custom __eq__ other than object.__eq__
bool has_custom_eq = false; bool has_custom_eq = false;
if(ti->m__eq__) has_custom_eq = true; if(ti->m__eq__) has_custom_eq = true;
@ -825,10 +825,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)), Type(-1), nullptr, "object", true}); _all_types.push_back({heap._new<Type>(tp_type, tp_object), Type(), nullptr, "object", true});
_all_types.push_back({heap._new<Type>(Type(1), Type(1)), Type(0), nullptr, "type", false}); _all_types.push_back({heap._new<Type>(tp_type, tp_type), tp_object, nullptr, "type", false});
auto _new_type = [this](const char* name, Type base=Type(0), bool subclass_enabled=false){ auto _new_type = [this](const char* name, Type base=tp_object, bool subclass_enabled=false){
PyVar obj = new_type_object(nullptr, name, base, subclass_enabled); PyVar obj = new_type_object(nullptr, name, base, subclass_enabled);
return PK_OBJ_GET(Type, obj); return PK_OBJ_GET(Type, obj);
}; };
@ -849,10 +849,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", Type(0), true)) exit(-3); if(tp_exception != _new_type("Exception", tp_object, 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", Type(0), true)) exit(-3); // dict can be subclassed if(tp_dict != _new_type("dict", tp_object, 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);
@ -868,7 +868,7 @@ void VM::__init_builtin_types(){
this->Ellipsis = heap._new<Dummy>(_new_type("ellipsis")); this->Ellipsis = heap._new<Dummy>(_new_type("ellipsis"));
this->True = heap._new<Dummy>(tp_bool); this->True = heap._new<Dummy>(tp_bool);
this->False = heap._new<Dummy>(tp_bool); this->False = heap._new<Dummy>(tp_bool);
this->StopIteration = _all_types[_new_type("StopIteration", tp_exception).index].obj; this->StopIteration = _all_types[_new_type("StopIteration", tp_exception)].obj;
this->builtins = new_module("builtins"); this->builtins = new_module("builtins");
@ -1196,7 +1196,7 @@ PyVar VM::getattr(PyVar obj, StrName name, bool throw_err){
return cls_var; return cls_var;
} }
const PyTypeInfo* ti = &_all_types[objtype.index]; const PyTypeInfo* ti = &_all_types[objtype];
if(ti->m__getattr__){ if(ti->m__getattr__){
PyVar ret = ti->m__getattr__(this, obj, name); PyVar ret = ti->m__getattr__(this, obj, name);
if(ret) return ret; if(ret) return ret;
@ -1267,7 +1267,7 @@ PyVar VM::get_unbound_method(PyVar obj, StrName name, PyVar* self, bool throw_er
return cls_var; return cls_var;
} }
const PyTypeInfo* ti = &_all_types[objtype.index]; const PyTypeInfo* ti = &_all_types[objtype];
if(fallback && ti->m__getattr__){ if(fallback && ti->m__getattr__){
PyVar ret = ti->m__getattr__(this, obj, name); PyVar ret = ti->m__getattr__(this, obj, name);
if(ret) return ret; if(ret) return ret;
@ -1301,7 +1301,7 @@ void VM::setattr(PyVar obj, StrName name, PyVar value){
} }
} }
const PyTypeInfo* ti = &_all_types[objtype.index]; const PyTypeInfo* ti = &_all_types[objtype];
if(ti->m__setattr__){ if(ti->m__setattr__){
ti->m__setattr__(this, obj, name, value); ti->m__setattr__(this, obj, name, value);
return; return;
@ -1429,7 +1429,7 @@ void ManagedHeap::mark() {
} }
StrName _type_name(VM *vm, Type type){ StrName _type_name(VM *vm, Type type){
return vm->_all_types[type.index].name; return vm->_all_types[type].name;
} }
void _gc_mark_namedict(NameDict* t){ void _gc_mark_namedict(NameDict* t){
@ -1439,14 +1439,14 @@ void _gc_mark_namedict(NameDict* t){
} }
void VM::bind__getitem__(Type type, PyVar (*f)(VM*, PyVar, PyVar)){ void VM::bind__getitem__(Type type, PyVar (*f)(VM*, PyVar, PyVar)){
_all_types[type.index].m__getitem__ = f; _all_types[type].m__getitem__ = f;
bind_func(type, __getitem__, 2, [](VM* vm, ArgsView args){ bind_func(type, __getitem__, 2, [](VM* vm, ArgsView args){
return lambda_get_userdata<PyVar(*)(VM*, PyVar, PyVar)>(args.begin())(vm, args[0], args[1]); return lambda_get_userdata<PyVar(*)(VM*, PyVar, PyVar)>(args.begin())(vm, args[0], args[1]);
}, f); }, f);
} }
void VM::bind__setitem__(Type type, void (*f)(VM*, PyVar, PyVar, PyVar)){ void VM::bind__setitem__(Type type, void (*f)(VM*, PyVar, PyVar, PyVar)){
_all_types[type.index].m__setitem__ = f; _all_types[type].m__setitem__ = f;
bind_func(type, __setitem__, 3, [](VM* vm, ArgsView args){ bind_func(type, __setitem__, 3, [](VM* vm, ArgsView args){
lambda_get_userdata<void(*)(VM* vm, PyVar, PyVar, PyVar)>(args.begin())(vm, args[0], args[1], args[2]); lambda_get_userdata<void(*)(VM* vm, PyVar, PyVar, PyVar)>(args.begin())(vm, args[0], args[1], args[2]);
return vm->None; return vm->None;
@ -1454,7 +1454,7 @@ void VM::bind__setitem__(Type type, void (*f)(VM*, PyVar, PyVar, PyVar)){
} }
void VM::bind__delitem__(Type type, void (*f)(VM*, PyVar, PyVar)){ void VM::bind__delitem__(Type type, void (*f)(VM*, PyVar, PyVar)){
_all_types[type.index].m__delitem__ = f; _all_types[type].m__delitem__ = f;
bind_func(type, __delitem__, 2, [](VM* vm, ArgsView args){ bind_func(type, __delitem__, 2, [](VM* vm, ArgsView args){
lambda_get_userdata<void(*)(VM*, PyVar, PyVar)>(args.begin())(vm, args[0], args[1]); lambda_get_userdata<void(*)(VM*, PyVar, PyVar)>(args.begin())(vm, args[0], args[1]);
return vm->None; return vm->None;
@ -1470,7 +1470,7 @@ PyVar VM::__pack_next_retval(unsigned n){
} }
void VM::bind__next__(Type type, unsigned (*f)(VM*, PyVar)){ void VM::bind__next__(Type type, unsigned (*f)(VM*, PyVar)){
_all_types[type.index].m__next__ = f; _all_types[type].m__next__ = f;
bind_func(type, __next__, 1, [](VM* vm, ArgsView args){ bind_func(type, __next__, 1, [](VM* vm, ArgsView args){
int n = lambda_get_userdata<unsigned(*)(VM*, PyVar)>(args.begin())(vm, args[0]); int n = lambda_get_userdata<unsigned(*)(VM*, PyVar)>(args.begin())(vm, args[0]);
return vm->__pack_next_retval(n); return vm->__pack_next_retval(n);
@ -1486,7 +1486,7 @@ void VM::bind__next__(Type type, PyVar (*f)(VM*, PyVar)){
#define BIND_UNARY_SPECIAL(name) \ #define BIND_UNARY_SPECIAL(name) \
void VM::bind##name(Type type, PyVar (*f)(VM*, PyVar)){ \ void VM::bind##name(Type type, PyVar (*f)(VM*, PyVar)){ \
_all_types[type.index].m##name = f; \ _all_types[type].m##name = f; \
bind_func(type, name, 1, [](VM* vm, ArgsView args){ \ bind_func(type, name, 1, [](VM* vm, ArgsView args){ \
return lambda_get_userdata<PyVar(*)(VM*, PyVar)>(args.begin())(vm, args[0]);\ return lambda_get_userdata<PyVar(*)(VM*, PyVar)>(args.begin())(vm, args[0]);\
}, f); \ }, f); \
@ -1497,7 +1497,7 @@ void VM::bind__next__(Type type, PyVar (*f)(VM*, PyVar)){
#undef BIND_UNARY_SPECIAL #undef BIND_UNARY_SPECIAL
void VM::bind__str__(Type type, Str (*f)(VM*, PyVar)){ void VM::bind__str__(Type type, Str (*f)(VM*, PyVar)){
_all_types[type.index].m__str__ = f; _all_types[type].m__str__ = f;
bind_func(type, __str__, 1, [](VM* vm, ArgsView args){ bind_func(type, __str__, 1, [](VM* vm, ArgsView args){
Str s = lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0]); Str s = lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0]);
return VAR(s); return VAR(s);
@ -1505,7 +1505,7 @@ void VM::bind__str__(Type type, Str (*f)(VM*, PyVar)){
} }
void VM::bind__repr__(Type type, Str (*f)(VM*, PyVar)){ void VM::bind__repr__(Type type, Str (*f)(VM*, PyVar)){
_all_types[type.index].m__repr__ = f; _all_types[type].m__repr__ = f;
bind_func(type, __repr__, 1, [](VM* vm, ArgsView args){ bind_func(type, __repr__, 1, [](VM* vm, ArgsView args){
Str s = lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0]); Str s = lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0]);
return VAR(s); return VAR(s);
@ -1513,7 +1513,7 @@ void VM::bind__repr__(Type type, Str (*f)(VM*, PyVar)){
} }
void VM::bind__hash__(Type type, i64 (*f)(VM*, PyVar)){ void VM::bind__hash__(Type type, i64 (*f)(VM*, PyVar)){
_all_types[type.index].m__hash__ = f; _all_types[type].m__hash__ = f;
bind_func(type, __hash__, 1, [](VM* vm, ArgsView args){ bind_func(type, __hash__, 1, [](VM* vm, ArgsView args){
i64 ret = lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0]); i64 ret = lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0]);
return VAR(ret); return VAR(ret);
@ -1521,7 +1521,7 @@ void VM::bind__hash__(Type type, i64 (*f)(VM*, PyVar)){
} }
void VM::bind__len__(Type type, i64 (*f)(VM*, PyVar)){ void VM::bind__len__(Type type, i64 (*f)(VM*, PyVar)){
_all_types[type.index].m__len__ = f; _all_types[type].m__len__ = f;
bind_func(type, __len__, 1, [](VM* vm, ArgsView args){ bind_func(type, __len__, 1, [](VM* vm, ArgsView args){
i64 ret = lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0]); i64 ret = lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0]);
return VAR(ret); return VAR(ret);
@ -1531,7 +1531,7 @@ void VM::bind__len__(Type type, i64 (*f)(VM*, PyVar)){
#define BIND_BINARY_SPECIAL(name) \ #define BIND_BINARY_SPECIAL(name) \
void VM::bind##name(Type type, BinaryFuncC f){ \ void VM::bind##name(Type type, BinaryFuncC f){ \
_all_types[type.index].m##name = f; \ _all_types[type].m##name = f; \
bind_func(type, name, 2, [](VM* vm, ArgsView args){ \ bind_func(type, name, 2, [](VM* vm, ArgsView args){ \
return lambda_get_userdata<BinaryFuncC>(args.begin())(vm, args[0], args[1]);\ return lambda_get_userdata<BinaryFuncC>(args.begin())(vm, args[0], args[1]);\
}, f); \ }, f); \