blueloveTH 2 лет назад
Родитель
Сommit
25d06bdb44
5 измененных файлов с 43 добавлено и 51 удалено
  1. 4 3
      include/pocketpy/cffi.h
  2. 0 6
      include/pocketpy/obj.h
  3. 10 39
      include/pocketpy/vm.h
  4. 1 1
      src/pocketpy.cpp
  5. 28 2
      src/vm.cpp

+ 4 - 3
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);             \

+ 0 - 6
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 <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 {};
 

+ 10 - 39
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<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);
-    }
+    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<typename T, typename __T>
     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, T());
+            return vm->heap.gcnew<T>(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<float>(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<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);
     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<double>(VM* vm, PyObject* obj){

+ 1 - 1
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<intptr_t>(obj) << ">";
         return VAR(ss.str());
     });

+ 28 - 2
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<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*)){
     PyObject* obj = _t(type);
     _all_types[type].m__hash__ = f;