From 25d06bdb441e87e023ee43c2f51659bbab3a37b2 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Fri, 19 Jan 2024 14:50:06 +0800 Subject: [PATCH] remove `OBJ_NAME` --- include/pocketpy/cffi.h | 7 +++--- include/pocketpy/obj.h | 6 ----- include/pocketpy/vm.h | 49 +++++++++-------------------------------- src/pocketpy.cpp | 2 +- src/vm.cpp | 30 +++++++++++++++++++++++-- 5 files changed, 43 insertions(+), 51 deletions(-) diff --git a/include/pocketpy/cffi.h b/include/pocketpy/cffi.h index a60cb11a..58531dd8 100644 --- a/include/pocketpy/cffi.h +++ b/include/pocketpy/cffi.h @@ -13,12 +13,13 @@ namespace pkpy { } \ static void _check_type(VM* vm, PyObject* val){ \ 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) { \ - if(OBJ_NAME(mod) != #mod) { \ - Str msg = fmt("register_class() failed: ", OBJ_NAME(mod), " != ", #mod); \ + std::string_view mod_name = PK_OBJ_GET(Str, mod->attr("__name__")).sv(); \ + if(mod_name != #mod) { \ + Str msg = fmt("register_class() failed: ", mod_name, " != ", #mod); \ throw std::runtime_error(msg.str()); \ } \ PyObject* type = vm->new_type_object(mod, #name, base); \ diff --git a/include/pocketpy/obj.h b/include/pocketpy/obj.h index 32a9b6ee..2b97c0fd 100644 --- a/include/pocketpy/obj.h +++ b/include/pocketpy/obj.h @@ -209,12 +209,6 @@ inline void gc_mark_namedict(NameDict& t){ 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 struct is_py_class : std::false_type {}; template struct is_py_class> : std::true_type {}; diff --git a/include/pocketpy/vm.h b/include/pocketpy/vm.h index 8bc71e51..ebb79e8a 100644 --- a/include/pocketpy/vm.h +++ b/include/pocketpy/vm.h @@ -284,31 +284,9 @@ public: #undef BIND_BINARY_SPECIAL - void 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(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(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(args.begin())(vm, args[0], args[1]); - return vm->None; - }); - PK_OBJ_GET(NativeFunc, nf).set_userdata(f); - } + void bind__getitem__(Type type, PyObject* (*f)(VM*, PyObject*, PyObject*)); + void bind__setitem__(Type type, void (*f)(VM*, PyObject*, PyObject*, PyObject*)); + void bind__delitem__(Type type, void (*f)(VM*, PyObject*, PyObject*)); bool py_eq(PyObject* lhs, PyObject* rhs); // new in v1.2.9 @@ -327,8 +305,7 @@ public: template PyObject* bind_default_constructor(__T&& type) { 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, T()); + return vm->heap.gcnew(PK_OBJ_GET(Type, args[0]), T()); }); } @@ -367,28 +344,22 @@ public: void ImportError(const Str& msg){ _builtin_error("ImportError", msg); } void AttributeError(PyObject* obj, StrName name){ - // OBJ_NAME calls getattr, which may lead to a infinite recursion 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{ - _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 check_type(PyObject* obj, Type type){ if(is_type(obj, type)) return; - TypeError("expected " + OBJ_NAME(_t(type)).escape() + ", got " + OBJ_NAME(_t(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)); + TypeError("expected " + _type_name(vm, type).escape() + ", got " + _type_name(vm, _tp(obj)).escape()); } void check_non_tagged_type(PyObject* obj, Type type){ 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){ @@ -513,7 +484,7 @@ template<> inline float py_cast(VM* vm, PyObject* obj){ if(is_float(obj)) return untag_float(obj); i64 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; } template<> inline float _py_cast(VM* vm, PyObject* obj){ @@ -523,7 +494,7 @@ template<> inline double py_cast(VM* vm, PyObject* obj){ if(is_float(obj)) return untag_float(obj); i64 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; } template<> inline double _py_cast(VM* vm, PyObject* obj){ diff --git a/src/pocketpy.cpp b/src/pocketpy.cpp index a188152a..044de82f 100644 --- a/src/pocketpy.cpp +++ b/src/pocketpy.cpp @@ -301,7 +301,7 @@ void init_builtins(VM* _vm) { _vm->bind__repr__(VM::tp_object, [](VM* vm, PyObject* obj) { if(is_tagged(obj)) PK_FATAL_ERROR(); 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(obj) << ">"; return VAR(ss.str()); }); diff --git a/src/vm.cpp b/src/vm.cpp index a49444ed..863670ce 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -114,7 +114,7 @@ namespace pkpy{ PyObject* self; PyObject* iter_f = get_unbound_method(obj, __iter__, &self, false); 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; } @@ -978,7 +978,7 @@ __FAST_CALL: // [call_f, self, args..., kwargs...] 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() } @@ -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(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(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(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*)){ PyObject* obj = _t(type); _all_types[type].m__hash__ = f;