remove OBJ_NAME

This commit is contained in:
blueloveTH 2024-01-19 14:50:06 +08:00
parent 61f01d6455
commit 25d06bdb44
5 changed files with 43 additions and 51 deletions

View File

@ -13,12 +13,13 @@ namespace pkpy {
} \ } \
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 " + OBJ_NAME(vm->_t(val)).escape()); \ vm->TypeError("expected '" #mod "." #name "', got " + _type_name(vm, vm->_tp(val)).escape()); \
} \ } \
} \ } \
static PyObject* register_class(VM* vm, PyObject* mod, Type base=0) { \ static PyObject* register_class(VM* vm, PyObject* mod, Type base=0) { \
if(OBJ_NAME(mod) != #mod) { \ std::string_view mod_name = PK_OBJ_GET(Str, mod->attr("__name__")).sv(); \
Str msg = fmt("register_class() failed: ", OBJ_NAME(mod), " != ", #mod); \ if(mod_name != #mod) { \
Str msg = fmt("register_class() failed: ", mod_name, " != ", #mod); \
throw std::runtime_error(msg.str()); \ throw std::runtime_error(msg.str()); \
} \ } \
PyObject* type = vm->new_type_object(mod, #name, base); \ PyObject* type = vm->new_type_object(mod, #name, base); \

View File

@ -209,12 +209,6 @@ inline void gc_mark_namedict(NameDict& t){
StrName _type_name(VM* vm, Type type); StrName _type_name(VM* vm, Type type);
#if PK_DEBUG_NO_BUILTINS
#define OBJ_NAME(obj) Str("<?>")
#else
#define OBJ_NAME(obj) PK_OBJ_GET(Str, vm->getattr(obj, __name__))
#endif
template <typename, typename=void> struct is_py_class : std::false_type {}; template <typename, typename=void> struct is_py_class : std::false_type {};
template <typename T> struct is_py_class<T, std::void_t<decltype(T::_type)>> : std::true_type {}; template <typename T> struct is_py_class<T, std::void_t<decltype(T::_type)>> : std::true_type {};

View File

@ -284,31 +284,9 @@ public:
#undef BIND_BINARY_SPECIAL #undef BIND_BINARY_SPECIAL
void bind__getitem__(Type type, PyObject* (*f)(VM*, PyObject*, PyObject*)){ void bind__getitem__(Type type, PyObject* (*f)(VM*, PyObject*, PyObject*));
_all_types[type].m__getitem__ = f; void bind__setitem__(Type type, void (*f)(VM*, PyObject*, PyObject*, PyObject*));
PyObject* nf = bind_method<1>(type, "__getitem__", [](VM* vm, ArgsView args){ void bind__delitem__(Type type, void (*f)(VM*, PyObject*, PyObject*));
return lambda_get_userdata<PyObject*(*)(VM*, PyObject*, PyObject*)>(args.begin())(vm, args[0], args[1]);
});
PK_OBJ_GET(NativeFunc, nf).set_userdata(f);
}
void bind__setitem__(Type type, void (*f)(VM*, PyObject*, PyObject*, PyObject*)){
_all_types[type].m__setitem__ = f;
PyObject* nf = bind_method<2>(type, "__setitem__", [](VM* vm, ArgsView args){
lambda_get_userdata<void(*)(VM* vm, PyObject*, PyObject*, PyObject*)>(args.begin())(vm, args[0], args[1], args[2]);
return vm->None;
});
PK_OBJ_GET(NativeFunc, nf).set_userdata(f);
}
void bind__delitem__(Type type, void (*f)(VM*, PyObject*, PyObject*)){
_all_types[type].m__delitem__ = f;
PyObject* nf = bind_method<1>(type, "__delitem__", [](VM* vm, ArgsView args){
lambda_get_userdata<void(*)(VM*, PyObject*, PyObject*)>(args.begin())(vm, args[0], args[1]);
return vm->None;
});
PK_OBJ_GET(NativeFunc, nf).set_userdata(f);
}
bool py_eq(PyObject* lhs, PyObject* rhs); bool py_eq(PyObject* lhs, PyObject* rhs);
// new in v1.2.9 // new in v1.2.9
@ -327,8 +305,7 @@ public:
template<typename T, typename __T> template<typename T, typename __T>
PyObject* bind_default_constructor(__T&& type) { PyObject* bind_default_constructor(__T&& type) {
return bind_constructor<1>(std::forward<__T>(type), [](VM* vm, ArgsView args){ return bind_constructor<1>(std::forward<__T>(type), [](VM* vm, ArgsView args){
Type t = PK_OBJ_GET(Type, args[0]); return vm->heap.gcnew<T>(PK_OBJ_GET(Type, args[0]), T());
return vm->heap.gcnew<T>(t, T());
}); });
} }
@ -367,28 +344,22 @@ public:
void ImportError(const Str& msg){ _builtin_error("ImportError", msg); } void ImportError(const Str& msg){ _builtin_error("ImportError", msg); }
void AttributeError(PyObject* obj, StrName name){ void AttributeError(PyObject* obj, StrName name){
// OBJ_NAME calls getattr, which may lead to a infinite recursion
if(isinstance(obj, vm->tp_type)){ if(isinstance(obj, vm->tp_type)){
_builtin_error("AttributeError", fmt("type object ", OBJ_NAME(obj).escape(), " has no attribute ", name.escape())); _builtin_error("AttributeError", fmt("type object ", _type_name(vm, PK_OBJ_GET(Type, obj)).escape(), " has no attribute ", name.escape()));
}else{ }else{
_builtin_error("AttributeError", fmt(OBJ_NAME(_t(obj)).escape(), " object has no attribute ", name.escape())); _builtin_error("AttributeError", fmt(_type_name(vm, _tp(obj)).escape(), " object has no attribute ", name.escape()));
} }
} }
void AttributeError(const Str& msg){ _builtin_error("AttributeError", msg); } void AttributeError(const Str& msg){ _builtin_error("AttributeError", msg); }
void check_type(PyObject* obj, Type type){ void check_type(PyObject* obj, Type type){
if(is_type(obj, type)) return; if(is_type(obj, type)) return;
TypeError("expected " + OBJ_NAME(_t(type)).escape() + ", got " + OBJ_NAME(_t(obj)).escape()); TypeError("expected " + _type_name(vm, type).escape() + ", got " + _type_name(vm, _tp(obj)).escape());
}
void check_args_size(int size, int min_size, int max_size){
if(size >= min_size && size <= max_size) return;
TypeError(fmt("expected ", min_size, "-", max_size, " arguments, got ", size));
} }
void check_non_tagged_type(PyObject* obj, Type type){ void check_non_tagged_type(PyObject* obj, Type type){
if(is_non_tagged_type(obj, type)) return; if(is_non_tagged_type(obj, type)) return;
TypeError("expected " + OBJ_NAME(_t(type)).escape() + ", got " + OBJ_NAME(_t(obj)).escape()); TypeError("expected " + _type_name(vm, type).escape() + ", got " + _type_name(vm, _tp(obj)).escape());
} }
PyObject* _t(Type t){ PyObject* _t(Type t){
@ -513,7 +484,7 @@ template<> inline float py_cast<float>(VM* vm, PyObject* obj){
if(is_float(obj)) return untag_float(obj); if(is_float(obj)) return untag_float(obj);
i64 bits; i64 bits;
if(try_cast_int(obj, &bits)) return (float)bits; if(try_cast_int(obj, &bits)) return (float)bits;
vm->TypeError("expected 'int' or 'float', got " + OBJ_NAME(vm->_t(obj)).escape()); vm->TypeError("expected 'int' or 'float', got " + _type_name(vm, vm->_tp(obj)).escape());
return 0; return 0;
} }
template<> inline float _py_cast<float>(VM* vm, PyObject* obj){ template<> inline float _py_cast<float>(VM* vm, PyObject* obj){
@ -523,7 +494,7 @@ template<> inline double py_cast<double>(VM* vm, PyObject* obj){
if(is_float(obj)) return untag_float(obj); if(is_float(obj)) return untag_float(obj);
i64 bits; i64 bits;
if(try_cast_int(obj, &bits)) return (float)bits; if(try_cast_int(obj, &bits)) return (float)bits;
vm->TypeError("expected 'int' or 'float', got " + OBJ_NAME(vm->_t(obj)).escape()); vm->TypeError("expected 'int' or 'float', got " + _type_name(vm, vm->_tp(obj)).escape());
return 0; return 0;
} }
template<> inline double _py_cast<double>(VM* vm, PyObject* obj){ template<> inline double _py_cast<double>(VM* vm, PyObject* obj){

View File

@ -301,7 +301,7 @@ void init_builtins(VM* _vm) {
_vm->bind__repr__(VM::tp_object, [](VM* vm, PyObject* obj) { _vm->bind__repr__(VM::tp_object, [](VM* vm, PyObject* obj) {
if(is_tagged(obj)) PK_FATAL_ERROR(); if(is_tagged(obj)) PK_FATAL_ERROR();
std::stringstream ss; // hex std::stringstream ss; // hex
ss << "<" << OBJ_NAME(vm->_t(obj)) << " object at 0x"; ss << "<" << _type_name(vm, vm->_tp(obj)) << " object at 0x";
ss << std::hex << reinterpret_cast<intptr_t>(obj) << ">"; ss << std::hex << reinterpret_cast<intptr_t>(obj) << ">";
return VAR(ss.str()); return VAR(ss.str());
}); });

View File

@ -114,7 +114,7 @@ namespace pkpy{
PyObject* self; PyObject* self;
PyObject* iter_f = get_unbound_method(obj, __iter__, &self, false); PyObject* iter_f = get_unbound_method(obj, __iter__, &self, false);
if(self != PY_NULL) return call_method(self, iter_f); if(self != PY_NULL) return call_method(self, iter_f);
TypeError(OBJ_NAME(_t(obj)).escape() + " object is not iterable"); TypeError(_type_name(vm, _tp(obj)).escape() + " object is not iterable");
return nullptr; return nullptr;
} }
@ -978,7 +978,7 @@ __FAST_CALL:
// [call_f, self, args..., kwargs...] // [call_f, self, args..., kwargs...]
return vectorcall(ARGC, KWARGC, false); return vectorcall(ARGC, KWARGC, false);
} }
TypeError(OBJ_NAME(_t(callable)).escape() + " object is not callable"); TypeError(_type_name(vm, _tp(callable)).escape() + " object is not callable");
PK_UNREACHABLE() PK_UNREACHABLE()
} }
@ -1257,6 +1257,32 @@ StrName _type_name(VM *vm, Type type){
} }
void VM::bind__getitem__(Type type, PyObject* (*f)(VM*, PyObject*, PyObject*)){
_all_types[type].m__getitem__ = f;
PyObject* nf = bind_method<1>(type, "__getitem__", [](VM* vm, ArgsView args){
return lambda_get_userdata<PyObject*(*)(VM*, PyObject*, PyObject*)>(args.begin())(vm, args[0], args[1]);
});
PK_OBJ_GET(NativeFunc, nf).set_userdata(f);
}
void VM::bind__setitem__(Type type, void (*f)(VM*, PyObject*, PyObject*, PyObject*)){
_all_types[type].m__setitem__ = f;
PyObject* nf = bind_method<2>(type, "__setitem__", [](VM* vm, ArgsView args){
lambda_get_userdata<void(*)(VM* vm, PyObject*, PyObject*, PyObject*)>(args.begin())(vm, args[0], args[1], args[2]);
return vm->None;
});
PK_OBJ_GET(NativeFunc, nf).set_userdata(f);
}
void VM::bind__delitem__(Type type, void (*f)(VM*, PyObject*, PyObject*)){
_all_types[type].m__delitem__ = f;
PyObject* nf = bind_method<1>(type, "__delitem__", [](VM* vm, ArgsView args){
lambda_get_userdata<void(*)(VM*, PyObject*, PyObject*)>(args.begin())(vm, args[0], args[1]);
return vm->None;
});
PK_OBJ_GET(NativeFunc, nf).set_userdata(f);
}
void VM::bind__hash__(Type type, i64 (*f)(VM*, PyObject*)){ void VM::bind__hash__(Type type, i64 (*f)(VM*, PyObject*)){
PyObject* obj = _t(type); PyObject* obj = _t(type);
_all_types[type].m__hash__ = f; _all_types[type].m__hash__ = f;