Skip to content

Commit 1c8cbe4

Browse files
committed
Use class handlers for GMP serialization
A bit faster and less boilerplate
1 parent 8860758 commit 1c8cbe4

File tree

1 file changed

+29
-46
lines changed

1 file changed

+29
-46
lines changed

ext/gmp/gmp.c

Lines changed: 29 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
#include "ext/standard/php_var.h"
2828
#include "ext/standard/php_smart_str_public.h"
2929
#include "zend_exceptions.h"
30-
#include "zend_interfaces.h"
3130

3231
#if HAVE_GMP
3332

@@ -686,57 +685,51 @@ static int gmp_compare(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
686685
}
687686
/* }}} */
688687

689-
PHP_METHOD(GMP, serialize) /* {{{ */
688+
static int gmp_serialize(zval *object, unsigned char **buffer, zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC) /* {{{ */
690689
{
691-
mpz_ptr gmpnum = GET_GMP_FROM_ZVAL(getThis());
690+
mpz_ptr gmpnum = GET_GMP_FROM_ZVAL(object);
692691
smart_str buf = {0};
693-
php_serialize_data_t var_hash;
694692
zval zv, *zv_ptr = &zv;
693+
php_serialize_data_t *serialize_data = (php_serialize_data_t *) data;
695694

696-
if (zend_parse_parameters_none() == FAILURE) {
697-
return;
698-
}
699-
700-
PHP_VAR_SERIALIZE_INIT(var_hash);
695+
PHP_VAR_SERIALIZE_INIT(*serialize_data);
701696

702697
INIT_PZVAL(zv_ptr);
703698

704699
gmp_strval(zv_ptr, gmpnum, 10);
705-
php_var_serialize(&buf, &zv_ptr, &var_hash TSRMLS_CC);
700+
php_var_serialize(&buf, &zv_ptr, serialize_data TSRMLS_CC);
706701
zval_dtor(zv_ptr);
707702

708-
Z_ARRVAL_P(zv_ptr) = zend_std_get_properties(getThis() TSRMLS_CC);
703+
Z_ARRVAL_P(zv_ptr) = zend_std_get_properties(object TSRMLS_CC);
709704
Z_TYPE_P(zv_ptr) = IS_ARRAY;
710-
php_var_serialize(&buf, &zv_ptr, &var_hash TSRMLS_CC);
705+
php_var_serialize(&buf, &zv_ptr, serialize_data TSRMLS_CC);
711706

712-
PHP_VAR_SERIALIZE_DESTROY(var_hash);
707+
PHP_VAR_SERIALIZE_DESTROY(*serialize_data);
713708

714-
if (buf.c) {
715-
RETURN_STRINGL(buf.c, buf.len, 0);
716-
}
709+
*buffer = (unsigned char *) buf.c;
710+
*buf_len = buf.len;
711+
712+
return SUCCESS;
717713
}
718714
/* }}} */
719715

720-
PHP_METHOD(GMP, unserialize) /* {{{ */
716+
static int gmp_unserialize(zval **object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC) /* {{{ */
721717
{
722-
mpz_ptr gmpnum = GET_GMP_FROM_ZVAL(getThis());
723-
char *str;
724-
int str_len;
725-
php_unserialize_data_t var_hash;
718+
mpz_ptr gmpnum;
726719
const unsigned char *p, *max;
727720
zval zv, *zv_ptr = &zv;
721+
int retval = FAILURE;
722+
php_unserialize_data_t *unserialize_data = (php_unserialize_data_t *) data;
728723

729-
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {
730-
return;
731-
}
724+
PHP_VAR_UNSERIALIZE_INIT(*unserialize_data);
732725

733-
PHP_VAR_UNSERIALIZE_INIT(var_hash);
726+
gmp_create_ex(*object, &gmpnum TSRMLS_CC);
734727

735-
p = (unsigned char *) str;
736-
max = (unsigned char *) str + str_len;
728+
p = buf;
729+
max = buf + buf_len;
737730

738731
INIT_ZVAL(zv);
739-
if (!php_var_unserialize(&zv_ptr, &p, max, &var_hash TSRMLS_CC)
732+
if (!php_var_unserialize(&zv_ptr, &p, max, unserialize_data TSRMLS_CC)
740733
|| Z_TYPE_P(zv_ptr) != IS_STRING
741734
|| convert_to_gmp(gmpnum, zv_ptr, 10 TSRMLS_CC) == FAILURE
742735
) {
@@ -746,7 +739,7 @@ PHP_METHOD(GMP, unserialize) /* {{{ */
746739
zval_dtor(&zv);
747740

748741
INIT_ZVAL(zv);
749-
if (!php_var_unserialize(&zv_ptr, &p, max, &var_hash TSRMLS_CC)
742+
if (!php_var_unserialize(&zv_ptr, &p, max, unserialize_data TSRMLS_CC)
750743
|| Z_TYPE_P(zv_ptr) != IS_ARRAY
751744
) {
752745
zend_throw_exception(NULL, "Could not unserialize properties", 0 TSRMLS_CC);
@@ -755,30 +748,19 @@ PHP_METHOD(GMP, unserialize) /* {{{ */
755748

756749
if (zend_hash_num_elements(Z_ARRVAL_P(zv_ptr)) != 0) {
757750
zend_hash_copy(
758-
zend_std_get_properties(getThis() TSRMLS_CC), Z_ARRVAL_P(zv_ptr),
751+
zend_std_get_properties(*object TSRMLS_CC), Z_ARRVAL_P(zv_ptr),
759752
(copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *)
760753
);
761754
}
762755

756+
retval = SUCCESS;
763757
exit:
764758
zval_dtor(&zv);
765-
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
759+
PHP_VAR_UNSERIALIZE_DESTROY(*unserialize_data);
760+
return retval;
766761
}
767762
/* }}} */
768763

769-
ZEND_BEGIN_ARG_INFO_EX(arginfo_serialize, 0, 0, 0)
770-
ZEND_END_ARG_INFO()
771-
772-
ZEND_BEGIN_ARG_INFO_EX(arginfo_unserialize, 0, 0, 1)
773-
ZEND_ARG_INFO(0, serialized)
774-
ZEND_END_ARG_INFO()
775-
776-
const zend_function_entry gmp_methods[] = {
777-
PHP_ME(GMP, serialize, arginfo_serialize, ZEND_ACC_PUBLIC)
778-
PHP_ME(GMP, unserialize, arginfo_unserialize, ZEND_ACC_PUBLIC)
779-
PHP_FE_END
780-
};
781-
782764
/* {{{ ZEND_GINIT_FUNCTION
783765
*/
784766
static ZEND_GINIT_FUNCTION(gmp)
@@ -792,10 +774,11 @@ static ZEND_GINIT_FUNCTION(gmp)
792774
ZEND_MINIT_FUNCTION(gmp)
793775
{
794776
zend_class_entry tmp_ce;
795-
INIT_CLASS_ENTRY(tmp_ce, "GMP", gmp_methods);
777+
INIT_CLASS_ENTRY(tmp_ce, "GMP", NULL);
796778
gmp_ce = zend_register_internal_class(&tmp_ce TSRMLS_CC);
797-
zend_class_implements(gmp_ce TSRMLS_CC, 1, zend_ce_serializable);
798779
gmp_ce->create_object = gmp_create_object;
780+
gmp_ce->serialize = gmp_serialize;
781+
gmp_ce->unserialize = gmp_unserialize;
799782

800783
memcpy(&gmp_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
801784
gmp_object_handlers.cast_object = gmp_cast_object;

0 commit comments

Comments
 (0)