From 825c5b6c8140c1d67e7f25543cd25b129d6e48cd Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 26 Dec 2023 11:25:29 +0800 Subject: [PATCH] Optimize code --- include/phpy.h | 22 ++++++++++++++++++++++ src/bridge/core.cc | 28 +++++++++++++++++++--------- src/php/dict.cc | 4 ++-- src/php/error.cc | 5 ++--- src/php/object.cc | 8 ++++---- src/python/array.cc | 17 +++++++---------- src/python/string.cc | 6 +++--- 7 files changed, 59 insertions(+), 31 deletions(-) diff --git a/include/phpy.h b/include/phpy.h index 69b4506..c8fb933 100644 --- a/include/phpy.h +++ b/include/phpy.h @@ -198,6 +198,8 @@ uint32_t phpy_object_iterator_index(zval *object); #define STR_AND_LEN(str) str, sizeof(str) - 1 +#define Py_TypeName(pv) Py_TYPE(pv)->tp_name + #ifndef Py_IsTrue #define Py_IsTrue PyObject_IsTrue #endif @@ -300,6 +302,26 @@ struct CallObject { ~CallObject(); void call(); }; +class StrObject { + private: + PyObject *str_ = nullptr; + ssize_t len_; + const char *val_; + + public: + StrObject(PyObject *pv); + ~StrObject() { + if (str_) { + Py_DECREF(str_); + } + } + const char *val() { + return val_; + } + ssize_t len() { + return len_; + } +}; namespace python { PyObject *new_array(zval *zv); PyObject *new_array(PyObject *pv); diff --git a/src/bridge/core.cc b/src/bridge/core.cc index a349dff..7d8bebb 100644 --- a/src/bridge/core.cc +++ b/src/bridge/core.cc @@ -23,6 +23,7 @@ END_EXTERN_C() #include "zend_exceptions.h" using phpy::CallObject; +using phpy::StrObject; const int var_dump_level = 3; @@ -246,10 +247,8 @@ static void dict2array(PyObject *pv, zval *zv) { auto value = PyDict_GetItem(pv, next); zval item; py2php_fn(value, &item); - - ssize_t len; - const char *key = phpy::python::string2utf8(PyObject_Str(next), &len); - add_assoc_zval_ex(zv, key, len, &item); + StrObject key(next); + add_assoc_zval_ex(zv, key.val(), key.len(), &item); } Py_DECREF(iter); } @@ -323,14 +322,18 @@ void debug_dump(uint32_t i, zval *item) { printf("[%d] type=%d, ptr=%p \n", i, item->u1.v.type, item->value.arr); } -void debug_dump(uint32_t i, PyObject *pObj) { +void debug_dump(uint32_t i, PyObject *pv) { ssize_t len; + PyObject *str = PyObject_Str(pv); + PyObject *repr = PyObject_Repr(pv); printf("[%d] type=%s, str=%s, repr=%s, ptr=%p\n", i, - Py_TYPE(pObj)->tp_name, - phpy::python::string2utf8(PyObject_Str(pObj), &len), - phpy::python::string2utf8(PyObject_Repr(pObj), &len), - pObj); + Py_TypeName(pv), + phpy::python::string2utf8(str, &len), + phpy::python::string2utf8(repr, &len), + pv); + Py_DECREF(str); + Py_DECREF(repr); } void var_dump(zval *var) { @@ -429,6 +432,13 @@ void CallObject::parse_args(zval *array) { Py_DECREF(arg_list); } +StrObject::StrObject(PyObject *pv) { + if (!PyUnicode_Check(pv)) { + pv = str_ = PyObject_Str(pv); + } + val_ = phpy::python::string2utf8(pv, &len_); +} + namespace phpy { namespace python { const char *string2utf8(PyObject *pv, ssize_t *len) { diff --git a/src/php/dict.cc b/src/php/dict.cc index 7a67533..83e886c 100644 --- a/src/php/dict.cc +++ b/src/php/dict.cc @@ -71,9 +71,9 @@ ZEND_METHOD(PyDict, offsetGet) { }; auto value = PyDict_GetItem(object, pk); if (value == NULL) { - ssize_t len; PyErr_Print(); - zend_throw_error(NULL, "PyDict: error key [%s]", phpy::python::string2utf8(pk, &len)); + phpy::StrObject key(pk); + zend_throw_error(NULL, "PyDict: error key [%s]", key.val()); return; } py2php(value, return_value); diff --git a/src/php/error.cc b/src/php/error.cc index fc65516..0563e5f 100644 --- a/src/php/error.cc +++ b/src/php/error.cc @@ -43,9 +43,8 @@ void new_error(zval *zv, PyObject *error) { PyObject *pstr = PyObject_Str(pvalue); if (pstr) { - ssize_t len; - const char *error_message = phpy::python::string2utf8(pstr, &len); - zend_update_property_stringl(PyError_ce, Z_OBJ_P(zv), STR_AND_LEN("message"), error_message, len); + phpy::StrObject msg(pstr); + zend_update_property_stringl(PyError_ce, Z_OBJ_P(zv), STR_AND_LEN("message"), msg.val(), msg.len()); } } if (ptype) { diff --git a/src/php/object.cc b/src/php/object.cc index 39031d4..86a2e8a 100644 --- a/src/php/object.cc +++ b/src/php/object.cc @@ -230,7 +230,7 @@ ZEND_METHOD(PyObject, __get) { Py_DECREF(value); } else { PyErr_Print(); - zend_throw_error(NULL, "PyObject<%s> has no attribute '%s'", Py_TYPE(object)->tp_name, name); + zend_throw_error(NULL, "PyObject<%s> has no attribute '%s'", Py_TypeName(object), name); } } @@ -248,7 +248,7 @@ ZEND_METHOD(PyObject, __set) { auto value = PyObject_SetAttrString(object, name, php2py(zvalue)); if (value < 0) { PyErr_Print(); - zend_throw_error(NULL, "PyObject<%s> cannot write attribute '%s'", Py_TYPE(object)->tp_name, name); + zend_throw_error(NULL, "PyObject<%s> cannot write attribute '%s'", Py_TypeName(object), name); } } @@ -262,7 +262,7 @@ ZEND_METHOD(PyObject, __toString) { Py_DECREF(value); } else { PyErr_Print(); - zend_throw_error(NULL, "PyObject<%s> has no attribute '__str__'", Py_TYPE(object)->tp_name); + zend_throw_error(NULL, "PyObject<%s> has no attribute '__str__'", Py_TypeName(object)); return; } } @@ -280,7 +280,7 @@ ZEND_METHOD(PyObject, __invoke) { auto object = phpy_object_get_handle(ZEND_THIS); if (!object || !PyCallable_Check(object)) { PyErr_Print(); - zend_throw_error(NULL, "PyObject<%s>: object is not callable", Py_TYPE(object)->tp_name); + zend_throw_error(NULL, "PyObject<%s>: object is not callable", Py_TypeName(object)); return; } diff --git a/src/python/array.cc b/src/python/array.cc index 7a861b0..7464bc2 100644 --- a/src/python/array.cc +++ b/src/python/array.cc @@ -77,9 +77,8 @@ static PyObject *Array_getitem(ZendArray *self, PyObject *key) { if (PyLong_Check(key)) { result = phpy::php::array_get(&self->array, PyLong_AsLong(key)); } else { - ssize_t l_key; - auto skey = phpy::python::string2utf8(key, &l_key); - result = phpy::php::array_get(&self->array, skey, l_key); + phpy::StrObject dkey(key); + result = phpy::php::array_get(&self->array, dkey.val(), dkey.len()); } if (!result) { Py_RETURN_NONE; @@ -100,9 +99,8 @@ static bool Array_delitem(ZendArray *self, PyObject *key) { if (PyLong_Check(key)) { result = zend_hash_index_del(Z_ARR(self->array), PyLong_AsLong(key)); } else { - ssize_t l_key; - auto skey = phpy::python::string2utf8(key, &l_key); - result = zend_hash_str_del(Z_ARR(self->array), skey, l_key); + phpy::StrObject dkey(key); + result = zend_hash_str_del(Z_ARR(self->array), dkey.val(), dkey.len()); } return result == SUCCESS; } @@ -118,9 +116,8 @@ static int Array_setitem(ZendArray *self, PyObject *key, PyObject *value) { if (PyLong_Check(key)) { result = zend_hash_index_update(Z_ARR(self->array), PyLong_AsLong(key), &rv); } else { - ssize_t l_key; - auto skey = phpy::python::string2utf8(key, &l_key); - result = zend_hash_str_update(Z_ARR(self->array), skey, l_key, &rv); + phpy::StrObject dkey(key); + result = zend_hash_str_update(Z_ARR(self->array), dkey.val(), dkey.len(), &rv); } return result == NULL ? -1 : 0; } @@ -200,7 +197,7 @@ static PyObject *Array_next(ZendArray *self) { zend_ulong lval = 0; keytype = zend_hash_get_current_key_ex(Z_ARRVAL(self->array), &sval, &lval, &self->pos); - zend_hash_move_forward_ex(Z_ARRVAL(self->array), &self->pos); + zend_hash_move_forward_ex(Z_ARRVAL(self->array), &self->pos); if (HASH_KEY_IS_STRING == keytype) { return PyUnicode_FromStringAndSize(ZSTR_VAL(sval), ZSTR_LEN(sval)); diff --git a/src/python/string.cc b/src/python/string.cc index d03ccd9..e901eba 100644 --- a/src/python/string.cc +++ b/src/python/string.cc @@ -74,7 +74,7 @@ static PyObject *String_iadd(ZendString *self, PyObject *o2) { ssize_t s2_len; const char *s2 = phpy::python::string2char_ptr(o2, &s2_len); if (s2 == NULL) { - PyErr_Format(PyExc_TypeError, "can not concat '%s' to zend_string", Py_TYPE(o2)->tp_name); + PyErr_Format(PyExc_TypeError, "can not concat '%s' to zend_string", Py_TypeName(o2)); return NULL; } zend_string *new_zstr = zend_string_extend(Z_STR(self->string), s1_len + s2_len, 0); @@ -94,7 +94,7 @@ static PyObject *String_add(ZendString *self, PyObject *o2) { ssize_t s2_len; const char *s2 = phpy::python::string2char_ptr(o2, &s2_len); if (s2 == NULL) { - PyErr_Format(PyExc_TypeError, "can not concat '%s' to zend_string", Py_TYPE(o2)->tp_name); + PyErr_Format(PyExc_TypeError, "can not concat '%s' to zend_string", Py_TypeName(o2)); return NULL; } ZendString *new_str = (ZendString *) phpy::python::new_string(s1_len + (size_t) s2_len); @@ -211,7 +211,7 @@ PyObject *new_string(PyObject *pv) { Py_DECREF(value); } else { PyErr_Print(); - zend_throw_error(NULL, "PyObject<%s> has no attribute '__str__'", Py_TYPE(pv)->tp_name); + zend_throw_error(NULL, "PyObject<%s> has no attribute '__str__'", Py_TypeName(pv)); } } return (PyObject *) self;