]> granicus.if.org Git - php/commitdiff
Assign (un)serialize_func during compilation
authorNikita Popov <nikita.ppv@gmail.com>
Fri, 15 Feb 2019 10:20:28 +0000 (11:20 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Fri, 15 Feb 2019 10:20:28 +0000 (11:20 +0100)
This avoids writing this cache at runtime, which is illegal if
preloading is used.

Not every serialize/unserialize function actually belongs to the
Serializable interface, but I think it's not a problem to assign
these anyway -- whether they are used ultimately depends on whether
Serializable is implemented.

Alternatively it might make sense to just drop these entirely. I
don't think this is performance critical functionality.

Zend/zend_API.c
Zend/zend_compile.c
Zend/zend_inheritance.c

index f191ca25b98a3f18c8e82f8fb9439947724cb5af..97ccb611418b76d9fb98f93fd52ae359e846ee23 100644 (file)
@@ -2093,7 +2093,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
        int count=0, unload=0;
        HashTable *target_function_table = function_table;
        int error_type;
-       zend_function *ctor = NULL, *dtor = NULL, *clone = NULL, *__get = NULL, *__set = NULL, *__unset = NULL, *__isset = NULL, *__call = NULL, *__callstatic = NULL, *__tostring = NULL, *__debugInfo = NULL;
+       zend_function *ctor = NULL, *dtor = NULL, *clone = NULL, *__get = NULL, *__set = NULL, *__unset = NULL, *__isset = NULL, *__call = NULL, *__callstatic = NULL, *__tostring = NULL, *__debugInfo = NULL, *serialize_func = NULL, *unserialize_func = NULL;
        zend_string *lowercase_name;
        size_t fname_len;
        const char *lc_class_name = NULL;
@@ -2268,6 +2268,10 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
                         */
                        if ((fname_len == class_name_len) && !ctor && !memcmp(ZSTR_VAL(lowercase_name), lc_class_name, class_name_len+1)) {
                                ctor = reg_function;
+                       } else if (zend_string_equals_literal(lowercase_name, "serialize")) {
+                               serialize_func = reg_function;
+                       } else if (zend_string_equals_literal(lowercase_name, "unserialize")) {
+                               unserialize_func = reg_function;
                        } else if (ZSTR_VAL(lowercase_name)[0] != '_' || ZSTR_VAL(lowercase_name)[1] != '_') {
                                reg_function = NULL;
                        } else if (zend_string_equals_literal(lowercase_name, ZEND_CONSTRUCTOR_FUNC_NAME)) {
@@ -2339,6 +2343,8 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
                scope->__unset = __unset;
                scope->__isset = __isset;
                scope->__debugInfo = __debugInfo;
+               scope->serialize_func = serialize_func;
+               scope->unserialize_func = unserialize_func;
                if (ctor) {
                        ctor->common.fn_flags |= ZEND_ACC_CTOR;
                        if (ctor->common.fn_flags & ZEND_ACC_STATIC) {
index 03f8cf25638d48e09bb16b367670f4e65242f4ea..f814c48b3b8a7fb9c61c7a4a75d79548437a5260 100644 (file)
@@ -5637,6 +5637,10 @@ void zend_begin_method_decl(zend_op_array *op_array, zend_string *name, zend_boo
                        if (!ce->constructor) {
                                ce->constructor = (zend_function *) op_array;
                        }
+               } else if (zend_string_equals_literal(lcname, "serialize")) {
+                       ce->serialize_func = (zend_function *) op_array;
+               } else if (zend_string_equals_literal(lcname, "unserialize")) {
+                       ce->unserialize_func = (zend_function *) op_array;
                } else if (ZSTR_VAL(lcname)[0] != '_' || ZSTR_VAL(lcname)[1] != '_') {
                        if (!is_static) {
                                op_array->fn_flags |= ZEND_ACC_ALLOW_STATIC;
index 858a36213c251ebeba9c78e942bb1cf4aff0fa04..2ce4df30495b5d1ed3fb3e648b36310092487593 100644 (file)
@@ -124,9 +124,15 @@ static void do_inherit_parent_constructor(zend_class_entry *ce) /* {{{ */
        if (EXPECTED(!ce->clone)) {
                ce->clone = parent->clone;
        }
+       if (EXPECTED(!ce->serialize_func)) {
+               ce->serialize_func = parent->serialize_func;
+       }
        if (EXPECTED(!ce->serialize)) {
                ce->serialize = parent->serialize;
        }
+       if (EXPECTED(!ce->unserialize_func)) {
+               ce->unserialize_func = parent->unserialize_func;
+       }
        if (EXPECTED(!ce->unserialize)) {
                ce->unserialize = parent->unserialize;
        }
@@ -1287,7 +1293,11 @@ static void zend_do_implement_interfaces(zend_class_entry *ce) /* {{{ */
 
 static void zend_add_magic_methods(zend_class_entry* ce, zend_string* mname, zend_function* fe) /* {{{ */
 {
-       if (ZSTR_LEN(ce->name) != ZSTR_LEN(mname) && (ZSTR_VAL(mname)[0] != '_' || ZSTR_VAL(mname)[1] != '_')) {
+       if (zend_string_equals_literal(mname, "serialize")) {
+               ce->serialize_func = fe;
+       } else if (zend_string_equals_literal(mname, "unserialize")) {
+               ce->unserialize_func = fe;
+       } else if (ZSTR_LEN(ce->name) != ZSTR_LEN(mname) && (ZSTR_VAL(mname)[0] != '_' || ZSTR_VAL(mname)[1] != '_')) {
                /* pass */
        } else if (zend_string_equals_literal(mname, ZEND_CLONE_FUNC_NAME)) {
                ce->clone = fe;