diff --git a/docs/quick-start/interop.md b/docs/quick-start/interop.md index b98b9819..0183b5c0 100644 --- a/docs/quick-start/interop.md +++ b/docs/quick-start/interop.md @@ -39,4 +39,5 @@ std::cout << CAST(Str, i); // abc + `is_type(PyObject* obj, Type type)` + `is_non_tagged_type(PyObject* obj, Type type)` -+ `VM::check_type(PyObject* obj, Type type)` \ No newline at end of file ++ `VM::check_type(PyObject* obj, Type type)` ++ `VM::check_non_tagged_type(PyObject* obj, Type type)` \ No newline at end of file diff --git a/src/ceval.h b/src/ceval.h index bd5a4197..969a886a 100644 --- a/src/ceval.h +++ b/src/ceval.h @@ -487,7 +487,7 @@ __NEXT_STEP:; StrName name(byte.arg); PyObject* super_cls = POPX(); if(super_cls == None) super_cls = _t(tp_object); - check_type(super_cls, tp_type); + check_non_tagged_type(super_cls, tp_type); PyObject* cls = new_type_object(frame->_module, name, OBJ_GET(Type, super_cls)); PUSH(cls); } DISPATCH(); diff --git a/src/pocketpy.h b/src/pocketpy.h index aee2d6c1..2dd32c80 100644 --- a/src/pocketpy.h +++ b/src/pocketpy.h @@ -68,7 +68,7 @@ inline void init_builtins(VM* _vm) { }); _vm->bind_builtin_func<2>("super", [](VM* vm, ArgsView args) { - vm->check_type(args[0], vm->tp_type); + vm->check_non_tagged_type(args[0], vm->tp_type); Type type = OBJ_GET(Type, args[0]); if(!vm->isinstance(args[1], type)){ Str _0 = obj_type_name(vm, OBJ_GET(Type, vm->_t(args[1]))); @@ -80,7 +80,7 @@ inline void init_builtins(VM* _vm) { }); _vm->bind_builtin_func<2>("isinstance", [](VM* vm, ArgsView args) { - vm->check_type(args[1], vm->tp_type); + vm->check_non_tagged_type(args[1], vm->tp_type); Type type = OBJ_GET(Type, args[1]); return VAR(vm->isinstance(args[0], type)); }); diff --git a/src/vm.h b/src/vm.h index 682b1569..ceb6579d 100644 --- a/src/vm.h +++ b/src/vm.h @@ -30,14 +30,14 @@ inline int set_read_file_cwd(ReadFileCwdFunc func) { _read_file_cwd = func; retu #define DEF_NATIVE_2(ctype, ptype) \ template<> inline ctype py_cast(VM* vm, PyObject* obj) { \ - vm->check_type(obj, vm->ptype); \ + vm->check_non_tagged_type(obj, vm->ptype); \ return OBJ_GET(ctype, obj); \ } \ template<> inline ctype _py_cast(VM* vm, PyObject* obj) { \ return OBJ_GET(ctype, obj); \ } \ template<> inline ctype& py_cast(VM* vm, PyObject* obj) { \ - vm->check_type(obj, vm->ptype); \ + vm->check_non_tagged_type(obj, vm->ptype); \ return OBJ_GET(ctype, obj); \ } \ template<> inline ctype& _py_cast(VM* vm, PyObject* obj) { \ @@ -362,6 +362,21 @@ public: TypeError("expected " + OBJ_NAME(_t(type)).escape() + ", but got " + OBJ_NAME(_t(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() + ", but got " + OBJ_NAME(_t(obj)).escape()); + } + + void check_int(PyObject* obj){ + if(is_int(obj)) return; + check_type(obj, tp_int); + } + + void check_float(PyObject* obj){ + if(is_float(obj)) return; + check_type(obj, tp_float); + } + PyObject* _t(Type t){ return _all_types[t.index].obj; } @@ -434,7 +449,7 @@ DEF_NATIVE_2(MappingProxy, tp_mappingproxy) #define PY_CAST_INT(T) \ template<> inline T py_cast(VM* vm, PyObject* obj){ \ - vm->check_type(obj, vm->tp_int); \ + vm->check_int(obj); \ return (T)(BITS(obj) >> 2); \ } \ template<> inline T _py_cast(VM* vm, PyObject* obj){ \ @@ -454,7 +469,7 @@ PY_CAST_INT(unsigned long long) template<> inline float py_cast(VM* vm, PyObject* obj){ - vm->check_type(obj, vm->tp_float); + vm->check_float(obj); i64 bits = BITS(obj); bits = (bits >> 2) << 2; return BitsCvt(bits)._float; @@ -465,7 +480,7 @@ template<> inline float _py_cast(VM* vm, PyObject* obj){ return BitsCvt(bits)._float; } template<> inline double py_cast(VM* vm, PyObject* obj){ - vm->check_type(obj, vm->tp_float); + vm->check_float(obj); i64 bits = BITS(obj); bits = (bits >> 2) << 2; return BitsCvt(bits)._float; @@ -515,7 +530,7 @@ inline PyObject* py_var(VM* vm, bool val){ } template<> inline bool py_cast(VM* vm, PyObject* obj){ - vm->check_type(obj, vm->tp_bool); + vm->check_non_tagged_type(obj, vm->tp_bool); return obj == vm->True; } template<> inline bool _py_cast(VM* vm, PyObject* obj){ @@ -536,7 +551,7 @@ inline PyObject* py_var(VM* vm, std::string_view val){ template void _check_py_class(VM* vm, PyObject* obj){ - vm->check_type(obj, T::_type(vm)); + vm->check_non_tagged_type(obj, T::_type(vm)); } inline PyObject* VM::num_negated(PyObject* obj){ @@ -1169,7 +1184,7 @@ inline void VM::setattr(PyObject* obj, StrName name, PyObject* value){ template void VM::bind_method(PyObject* obj, Str name, NativeFuncC fn) { - check_type(obj, tp_type); + check_non_tagged_type(obj, tp_type); obj->attr().set(name, VAR(NativeFunc(fn, ARGC, true))); }