From 236902c629b6509f95c717eca95530b9575c39bb Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Sat, 18 May 2024 20:02:12 +0800 Subject: [PATCH] some fix --- include/pocketpy/common.h | 8 +++++--- include/pocketpy/vm.h | 36 +++++++++++++++++++++++------------- src/vm.cpp | 4 +--- 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/include/pocketpy/common.h b/include/pocketpy/common.h index d81a2c86..a6e3491d 100644 --- a/include/pocketpy/common.h +++ b/include/pocketpy/common.h @@ -189,7 +189,7 @@ struct PyVar final{ // uninitialized PyVar() = default; // constexpr initialized - constexpr PyVar(const const_sso_var&, Type type, i64 value): type(type), is_sso(true), flags(0), _0(0), _1(value) {} + constexpr PyVar(const const_sso_var&, Type type, int value): type(type), is_sso(true), flags(0), _0(value), _1(0) {} // zero initialized constexpr PyVar(std::nullptr_t): type(0), is_sso(false), flags(0), _0(0), _1(0) {} // PyObject* initialized (is_sso = false) @@ -213,12 +213,14 @@ struct PyVar final{ explicit operator bool() const { return (bool)type; } + i64 _qword(int i) const { return ((const i64*)this)[i]; } + bool operator==(const PyVar& other) const { - return memcmp(this, &other, sizeof(PyVar)) == 0; + return _qword(0) == other._qword(0) && _qword(1) == other._qword(1); } bool operator!=(const PyVar& other) const { - return memcmp(this, &other, sizeof(PyVar)) != 0; + return _qword(0) != other._qword(0) || _qword(1) != other._qword(1); } bool operator==(std::nullptr_t) const { return !(bool)type; } diff --git a/include/pocketpy/vm.h b/include/pocketpy/vm.h index 548d97c5..ed6d6d52 100644 --- a/include/pocketpy/vm.h +++ b/include/pocketpy/vm.h @@ -205,7 +205,10 @@ public: List py_list(PyVar); // x -> list(x) bool py_callable(PyVar obj); // x -> callable(x) - bool py_bool(PyVar obj); // x -> bool(x) + bool py_bool(PyVar obj){ // x -> bool(x) + if(obj.type == tp_bool) return obj._0; + return __py_bool_non_trivial(obj); + } i64 py_hash(PyVar obj); // x -> hash(x) bool py_eq(PyVar lhs, PyVar rhs); // (lhs, rhs) -> lhs == rhs @@ -449,6 +452,7 @@ public: void __push_varargs(PyVar _0, PyVar _1, PyVar _2, PyVar _3){ PUSH(_0); PUSH(_1); PUSH(_2); PUSH(_3); } PyVar __pack_next_retval(unsigned); PyVar __minmax_reduce(bool (VM::*op)(PyVar, PyVar), PyVar args, PyVar key); + bool __py_bool_non_trivial(PyVar); }; @@ -504,11 +508,17 @@ PyVar py_var(VM* vm, __T&& value){ if constexpr((bool)const_type){ if constexpr(is_sso_v) return PyVar(const_type, value); else return vm->heap.gcnew(const_type, std::forward<__T>(value)); + }else{ + Type type = vm->_find_type_in_cxx_typeid_map(); + if constexpr(is_sso_v) return PyVar(type, value); + else return vm->heap.gcnew(type, std::forward<__T>(value)); } } - Type type = vm->_find_type_in_cxx_typeid_map(); - if constexpr(is_sso_v) return PyVar(type, value); - else return vm->heap.gcnew(type, std::forward<__T>(value)); +} + +// fast path for bool if py_var<> cannot be inlined +inline PyVar py_var(VM* vm, bool value){ + return value ? vm->True : vm->False; } template @@ -530,18 +540,16 @@ __T _py_cast__internal(VM* vm, PyVar obj) { if(obj == vm->True) return true; if(obj == vm->False) return false; vm->TypeError("expected 'bool', got " + _type_name(vm, vm->_tp(obj)).escape()); - }else{ - return obj == vm->True; } + return obj == vm->True; }else if constexpr(is_integral_v){ static_assert(!std::is_reference_v<__T>); // int if constexpr(with_check){ if(is_int(obj)) return (T)obj.as(); vm->TypeError("expected 'int', got " + _type_name(vm, vm->_tp(obj)).escape()); - }else{ - return (T)obj.as(); } + return (T)obj.as(); }else if constexpr(is_floating_point_v){ static_assert(!std::is_reference_v<__T>); // float @@ -549,6 +557,7 @@ __T _py_cast__internal(VM* vm, PyVar obj) { i64 bits; if(try_cast_int(obj, &bits)) return (T)bits; vm->TypeError("expected 'int' or 'float', got " + _type_name(vm, vm->_tp(obj)).escape()); + return 0.0f; }else if constexpr(std::is_enum_v){ static_assert(!std::is_reference_v<__T>); return (__T)_py_cast__internal(vm, obj); @@ -567,13 +576,14 @@ __T _py_cast__internal(VM* vm, PyVar obj) { } } return PK_OBJ_GET(T, obj); + }else{ + if constexpr(with_check){ + Type type = vm->_find_type_in_cxx_typeid_map(); + vm->check_compatible_type(obj, type); + } + return PK_OBJ_GET(T, obj); } } - if constexpr(with_check){ - Type type = vm->_find_type_in_cxx_typeid_map(); - vm->check_compatible_type(obj, type); - } - return PK_OBJ_GET(T, obj); } template diff --git a/src/vm.cpp b/src/vm.cpp index 13686084..13485dd7 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -417,9 +417,7 @@ PyVar VM::py_negate(PyVar obj){ return call_method(obj, __neg__); } -bool VM::py_bool(PyVar obj){ - if(obj == vm->True) return true; - if(obj == vm->False) return false; +bool VM::__py_bool_non_trivial(PyVar obj){ if(obj == None) return false; if(is_int(obj)) return _CAST(i64, obj) != 0; if(is_float(obj)) return _CAST(f64, obj) != 0.0;