]> granicus.if.org Git - php/commitdiff
Avoid HashTable allocations for empty arrays (using zend_empty_array).
authorDmitry Stogov <dmitry@zend.com>
Tue, 24 Oct 2017 14:27:31 +0000 (17:27 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 24 Oct 2017 14:27:31 +0000 (17:27 +0300)
22 files changed:
Zend/zend_ast.c
Zend/zend_builtin_functions.c
Zend/zend_closures.c
Zend/zend_compile.c
Zend/zend_hash.c
Zend/zend_hash.h
Zend/zend_operators.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
ext/dom/xpath.c
ext/libxml/libxml.c
ext/mbstring/mbstring.c
ext/mysqli/mysqli_nonapi.c
ext/mysqli/mysqli_prop.c
ext/reflection/php_reflection.c
ext/simplexml/simplexml.c
ext/spl/spl_fixedarray.c
ext/sqlite3/sqlite3.c
ext/standard/array.c
ext/standard/var_unserializer.c
ext/standard/var_unserializer.re
ext/xsl/xsltprocessor.c

index 96bedb7b42ea724150c13da54cfcb95e720cd00b..9ace0790d548507e5610a598c32df215a8fb75f7 100644 (file)
@@ -408,10 +408,15 @@ ZEND_API int zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *sc
                        }
                        break;
                case ZEND_AST_ARRAY:
-                       array_init(result);
                        {
                                uint32_t i;
                                zend_ast_list *list = zend_ast_get_list(ast);
+
+                               if (!list->children) {
+                                       ZVAL_EMPTY_ARRAY(result);
+                                       break;
+                               }
+                               array_init(result);
                                for (i = 0; i < list->children; i++) {
                                        zend_ast *elem = list->child[i];
                                        if (elem->child[1]) {
index 5793ea33084e02f664f28cc9407fb9e4313f00f5..387e9f5e600b54181ca5e7975e567a2be91f98f6 100644 (file)
@@ -472,8 +472,8 @@ ZEND_FUNCTION(func_get_args)
 
        arg_count = ZEND_CALL_NUM_ARGS(ex);
 
-       array_init_size(return_value, arg_count);
        if (arg_count) {
+               array_init_size(return_value, arg_count);
                first_extra_arg = ex->func->op_array.num_args;
                zend_hash_real_init(Z_ARRVAL_P(return_value), 1);
                ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) {
@@ -512,6 +512,8 @@ ZEND_FUNCTION(func_get_args)
                        }
                } ZEND_HASH_FILL_END();
                Z_ARRVAL_P(return_value)->nNumOfElements = arg_count;
+       } else {
+               ZVAL_EMPTY_ARRAY(return_value);
        }
 }
 /* }}} */
@@ -2122,11 +2124,11 @@ static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array) /
 {
        uint32_t num_args = ZEND_CALL_NUM_ARGS(call);
 
-       array_init_size(arg_array, num_args);
        if (num_args) {
                uint32_t i = 0;
                zval *p = ZEND_CALL_ARG(call, 1);
 
+               array_init_size(arg_array, num_args);
                zend_hash_real_init(Z_ARRVAL_P(arg_array), 1);
                ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(arg_array)) {
                        if (call->func->type == ZEND_USER_FUNCTION) {
@@ -2184,6 +2186,8 @@ static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array) /
                        }
                } ZEND_HASH_FILL_END();
                Z_ARRVAL_P(arg_array)->nNumOfElements = num_args;
+       } else {
+               ZVAL_EMPTY_ARRAY(arg_array);
        }
 }
 /* }}} */
index eacd06ac4a3b7dc6be2c87b8919f62c0da378600..57d91c6635de8b758763316c39c80c5f23aedbbd 100644 (file)
@@ -251,8 +251,12 @@ static ZEND_NAMED_FUNCTION(zend_closure_call_magic) /* {{{ */ {
        fci.params = params;
        fci.param_count = 2;
        ZVAL_STR(&fci.params[0], EX(func)->common.function_name);
-       array_init(&fci.params[1]);
-       zend_copy_parameters_array(ZEND_NUM_ARGS(), &fci.params[1]);
+       if (ZEND_NUM_ARGS()) {
+               array_init_size(&fci.params[1], ZEND_NUM_ARGS());
+               zend_copy_parameters_array(ZEND_NUM_ARGS(), &fci.params[1]);
+       } else {
+               ZVAL_EMPTY_ARRAY(&fci.params[1]);
+       }
 
        fci.object = Z_OBJ(EX(This));
        fcc.object = Z_OBJ(EX(This));
index 5e85a2695743181be5d496e009b34de7a49b7173..96be2c60b22e7193bf49d10ee3c9caa4f8332d23 100644 (file)
@@ -6949,6 +6949,11 @@ static zend_bool zend_try_ct_eval_array(zval *result, zend_ast *ast) /* {{{ */
                return 0;
        }
 
+       if (!list->children) {
+               ZVAL_EMPTY_ARRAY(result);
+               return 1;
+       }
+
        array_init_size(result, list->children);
        for (i = 0; i < list->children; ++i) {
                zend_ast *elem_ast = list->child[i];
index d629c098dcebcca5a26032647791efbb880c9ba9..9f829ff9945662ef855f0f4c4b00b1fc0166e341 100644 (file)
@@ -157,6 +157,20 @@ static zend_always_inline void zend_hash_check_init(HashTable *ht, int packed)
 static const uint32_t uninitialized_bucket[-HT_MIN_MASK] =
        {HT_INVALID_IDX, HT_INVALID_IDX};
 
+ZEND_API const HashTable zend_empty_array = {
+       .gc.refcount = 2,
+       .gc.u.type_info = IS_ARRAY | (GC_IMMUTABLE << GC_FLAGS_SHIFT),
+       .u.flags = HASH_FLAG_STATIC_KEYS,
+       .nTableMask = HT_MIN_MASK,
+       .arData = (Bucket*)&uninitialized_bucket[2],
+       .nNumUsed = 0,
+       .nNumOfElements = 0,
+       .nTableSize = HT_MIN_SIZE,
+       .nInternalPointer = HT_INVALID_IDX,
+       .nNextFreeElement = 0,
+       .pDestructor = ZVAL_PTR_DTOR
+};
+
 static zend_always_inline void _zend_hash_init_int(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent)
 {
        GC_REFCOUNT(ht) = 1;
index e9518b88409be6ee4ed275fa3e31581e05b89fdb..ca1be3b0d0c18590b23ae2494993281e21a0e745 100644 (file)
 # define HT_ALLOW_COW_VIOLATION(ht)
 #endif
 
+extern ZEND_API const HashTable zend_empty_array;
+
+#define ZVAL_EMPTY_ARRAY(z) do {                                               \
+               zval *__z = (z);                                                                \
+               Z_ARR_P(__z) = (zend_array*)&zend_empty_array;  \
+               Z_TYPE_INFO_P(__z) = IS_ARRAY | (IS_TYPE_COPYABLE << Z_TYPE_FLAGS_SHIFT); \
+       } while (0)
+
+
 typedef struct _zend_hash_key {
        zend_ulong h;
        zend_string *key;
index fe6f97b12c324fc9c85a251614956acb817be8be..5270b6b39a995cbdb594406e80a9055edaf62169 100644 (file)
@@ -629,10 +629,12 @@ try_again:
                                }
 
                                zval_dtor(op);
+                               /*ZVAL_EMPTY_ARRAY(op);*/
                                array_init(op);
                        }
                        break;
                case IS_NULL:
+                       /*ZVAL_EMPTY_ARRAY(op);*/
                        array_init(op);
                        break;
                case IS_REFERENCE:
index 76589f30afd8876af5b960f5b820854fa0f0816d..0b36d2e7252c1c241669eea0d006631746f1c18b 100644 (file)
@@ -4782,7 +4782,7 @@ ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, NUM, ANY)
                        }
                } ZEND_HASH_FILL_END();
        } else {
-               array_init(params);
+               ZVAL_EMPTY_ARRAY(params);
        }
 
        ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -5263,19 +5263,16 @@ ZEND_VM_HANDLER(71, ZEND_INIT_ARRAY, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSED|NEXT|
        array = EX_VAR(opline->result.var);
        if (OP1_TYPE != IS_UNUSED) {
                size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
-       } else {
-               size = 0;
-       }
-       ZVAL_ARR(array, zend_new_array(size));
-
-       if (OP1_TYPE != IS_UNUSED) {
+               ZVAL_ARR(array, zend_new_array(size));
                /* Explicitly initialize array as not-packed if flag is set */
                if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
                        zend_hash_real_init(Z_ARRVAL_P(array), 0);
                }
+               ZEND_VM_DISPATCH_TO_HANDLER(ZEND_ADD_ARRAY_ELEMENT);
+       } else {
+               ZVAL_EMPTY_ARRAY(array);
+               ZEND_VM_NEXT_OPCODE();
        }
-
-       ZEND_VM_DISPATCH_TO_HANDLER(ZEND_ADD_ARRAY_ELEMENT);
 }
 
 ZEND_VM_HANDLER(21, ZEND_CAST, CONST|TMP|VAR|CV, ANY, TYPE)
@@ -5323,14 +5320,16 @@ ZEND_VM_HANDLER(21, ZEND_CAST, CONST|TMP|VAR|CV, ANY, TYPE)
 
                        if (opline->extended_value == IS_ARRAY) {
                                if (Z_TYPE_P(expr) != IS_OBJECT) {
-                                       ZVAL_ARR(result, zend_new_array(8));
                                        if (Z_TYPE_P(expr) != IS_NULL) {
+                                               ZVAL_ARR(result, zend_new_array(8));
                                                expr = zend_hash_index_add_new(Z_ARRVAL_P(result), 0, expr);
                                                if (OP1_TYPE == IS_CONST) {
                                                        if (UNEXPECTED(Z_OPT_REFCOUNTED_P(expr))) Z_ADDREF_P(expr);
                                                } else {
                                                        if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr);
                                                }
+                                       } else {
+                                               ZVAL_EMPTY_ARRAY(result);
                                        }
                                } else {
                                        ZVAL_COPY_VALUE(result, expr);
@@ -7819,11 +7818,11 @@ ZEND_VM_HANDLER(158, ZEND_CALL_TRAMPOLINE, ANY, ANY)
 
        SAVE_OPLINE();
 
-       args = zend_new_array(num_args);
        if (num_args) {
                zval *p = ZEND_CALL_ARG(execute_data, 1);
                zval *end = p + num_args;
 
+               args = zend_new_array(num_args);
                zend_hash_real_init(args, 1);
                ZEND_HASH_FILL_PACKED(args) {
                        do {
@@ -7842,7 +7841,11 @@ ZEND_VM_HANDLER(158, ZEND_CALL_TRAMPOLINE, ANY, ANY)
        ZEND_CALL_NUM_ARGS(call) = 2;
 
        ZVAL_STR(ZEND_CALL_ARG(call, 1), fbc->common.function_name);
-       ZVAL_ARR(ZEND_CALL_ARG(call, 2), args);
+       if (num_args) {
+               ZVAL_ARR(ZEND_CALL_ARG(call, 2), args);
+       } else {
+               ZVAL_EMPTY_ARRAY(ZEND_CALL_ARG(call, 2));
+       }
        zend_free_trampoline(fbc);
        fbc = call->func;
 
@@ -8316,11 +8319,11 @@ ZEND_VM_HANDLER(195, ZEND_FUNC_GET_ARGS, UNUSED|CONST, UNUSED)
                result_size = arg_count;
        }
 
-       ht = zend_new_array(result_size);
-       ZVAL_ARR(EX_VAR(opline->result.var), ht);
-
        if (result_size) {
                uint32_t first_extra_arg = EX(func)->op_array.num_args;
+
+               ht = zend_new_array(result_size);
+               ZVAL_ARR(EX_VAR(opline->result.var), ht);
                zend_hash_real_init(ht, 1);
                ZEND_HASH_FILL_PACKED(ht) {
                        zval *p, *q;
@@ -8364,6 +8367,8 @@ ZEND_VM_HANDLER(195, ZEND_FUNC_GET_ARGS, UNUSED|CONST, UNUSED)
                        }
                } ZEND_HASH_FILL_END();
                ht->nNumOfElements = result_size;
+       } else {
+               ZVAL_EMPTY_ARRAY(EX_VAR(opline->result.var));
        }
        ZEND_VM_NEXT_OPCODE();
 }
index bc846336fbc664faa43c45b414187ffea1639b33..1a24762e3680e1da07a91ec971f972b242d98292 100644 (file)
@@ -1501,7 +1501,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_HANDLER(ZEN
                        }
                } ZEND_HASH_FILL_END();
        } else {
-               array_init(params);
+               ZVAL_EMPTY_ARRAY(params);
        }
 
        ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -1967,11 +1967,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(Z
 
        SAVE_OPLINE();
 
-       args = zend_new_array(num_args);
        if (num_args) {
                zval *p = ZEND_CALL_ARG(execute_data, 1);
                zval *end = p + num_args;
 
+               args = zend_new_array(num_args);
                zend_hash_real_init(args, 1);
                ZEND_HASH_FILL_PACKED(args) {
                        do {
@@ -1990,7 +1990,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(Z
        ZEND_CALL_NUM_ARGS(call) = 2;
 
        ZVAL_STR(ZEND_CALL_ARG(call, 1), fbc->common.function_name);
-       ZVAL_ARR(ZEND_CALL_ARG(call, 2), args);
+       if (num_args) {
+               ZVAL_ARR(ZEND_CALL_ARG(call, 2), args);
+       } else {
+               ZVAL_EMPTY_ARRAY(ZEND_CALL_ARG(call, 2));
+       }
        zend_free_trampoline(fbc);
        fbc = call->func;
 
@@ -3395,14 +3399,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CONST_HANDLER(ZEND_O
 
                        if (opline->extended_value == IS_ARRAY) {
                                if (Z_TYPE_P(expr) != IS_OBJECT) {
-                                       ZVAL_ARR(result, zend_new_array(8));
                                        if (Z_TYPE_P(expr) != IS_NULL) {
+                                               ZVAL_ARR(result, zend_new_array(8));
                                                expr = zend_hash_index_add_new(Z_ARRVAL_P(result), 0, expr);
                                                if (IS_CONST == IS_CONST) {
                                                        if (UNEXPECTED(Z_OPT_REFCOUNTED_P(expr))) Z_ADDREF_P(expr);
                                                } else {
                                                        if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr);
                                                }
+                                       } else {
+                                               ZVAL_EMPTY_ARRAY(result);
                                        }
                                } else {
                                        ZVAL_COPY_VALUE(result, expr);
@@ -5934,19 +5940,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_CONST_HA
        array = EX_VAR(opline->result.var);
        if (IS_CONST != IS_UNUSED) {
                size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
-       } else {
-               size = 0;
-       }
-       ZVAL_ARR(array, zend_new_array(size));
-
-       if (IS_CONST != IS_UNUSED) {
+               ZVAL_ARR(array, zend_new_array(size));
                /* Explicitly initialize array as not-packed if flag is set */
                if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
                        zend_hash_real_init(Z_ARRVAL_P(array), 0);
                }
+               ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+       } else {
+               ZVAL_EMPTY_ARRAY(array);
+               ZEND_VM_NEXT_OPCODE();
        }
-
-       ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -7717,19 +7720,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_UNUSED_H
        array = EX_VAR(opline->result.var);
        if (IS_CONST != IS_UNUSED) {
                size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
-       } else {
-               size = 0;
-       }
-       ZVAL_ARR(array, zend_new_array(size));
-
-       if (IS_CONST != IS_UNUSED) {
+               ZVAL_ARR(array, zend_new_array(size));
                /* Explicitly initialize array as not-packed if flag is set */
                if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
                        zend_hash_real_init(Z_ARRVAL_P(array), 0);
                }
+               ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+       } else {
+               ZVAL_EMPTY_ARRAY(array);
+               ZEND_VM_NEXT_OPCODE();
        }
-
-       ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -8221,11 +8221,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FUNC_GET_ARGS_SPEC_CONST_UNUSE
                result_size = arg_count;
        }
 
-       ht = zend_new_array(result_size);
-       ZVAL_ARR(EX_VAR(opline->result.var), ht);
-
        if (result_size) {
                uint32_t first_extra_arg = EX(func)->op_array.num_args;
+
+               ht = zend_new_array(result_size);
+               ZVAL_ARR(EX_VAR(opline->result.var), ht);
                zend_hash_real_init(ht, 1);
                ZEND_HASH_FILL_PACKED(ht) {
                        zval *p, *q;
@@ -8269,6 +8269,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FUNC_GET_ARGS_SPEC_CONST_UNUSE
                        }
                } ZEND_HASH_FILL_END();
                ht->nNumOfElements = result_size;
+       } else {
+               ZVAL_EMPTY_ARRAY(EX_VAR(opline->result.var));
        }
        ZEND_VM_NEXT_OPCODE();
 }
@@ -9998,19 +10000,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_CV_HANDL
        array = EX_VAR(opline->result.var);
        if (IS_CONST != IS_UNUSED) {
                size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
-       } else {
-               size = 0;
-       }
-       ZVAL_ARR(array, zend_new_array(size));
-
-       if (IS_CONST != IS_UNUSED) {
+               ZVAL_ARR(array, zend_new_array(size));
                /* Explicitly initialize array as not-packed if flag is set */
                if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
                        zend_hash_real_init(Z_ARRVAL_P(array), 0);
                }
+               ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+       } else {
+               ZVAL_EMPTY_ARRAY(array);
+               ZEND_VM_NEXT_OPCODE();
        }
-
-       ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -12013,19 +12012,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR_H
        array = EX_VAR(opline->result.var);
        if (IS_CONST != IS_UNUSED) {
                size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
-       } else {
-               size = 0;
-       }
-       ZVAL_ARR(array, zend_new_array(size));
-
-       if (IS_CONST != IS_UNUSED) {
+               ZVAL_ARR(array, zend_new_array(size));
                /* Explicitly initialize array as not-packed if flag is set */
                if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
                        zend_hash_real_init(Z_ARRVAL_P(array), 0);
                }
+               ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+       } else {
+               ZVAL_EMPTY_ARRAY(array);
+               ZEND_VM_NEXT_OPCODE();
        }
-
-       ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -13038,14 +13034,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_TMP_HANDLER(ZEND_OPC
 
                        if (opline->extended_value == IS_ARRAY) {
                                if (Z_TYPE_P(expr) != IS_OBJECT) {
-                                       ZVAL_ARR(result, zend_new_array(8));
                                        if (Z_TYPE_P(expr) != IS_NULL) {
+                                               ZVAL_ARR(result, zend_new_array(8));
                                                expr = zend_hash_index_add_new(Z_ARRVAL_P(result), 0, expr);
                                                if (IS_TMP_VAR == IS_CONST) {
                                                        if (UNEXPECTED(Z_OPT_REFCOUNTED_P(expr))) Z_ADDREF_P(expr);
                                                } else {
                                                        if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr);
                                                }
+                                       } else {
+                                               ZVAL_EMPTY_ARRAY(result);
                                        }
                                } else {
                                        ZVAL_COPY_VALUE(result, expr);
@@ -13982,19 +13980,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_TMP_CONST_HAND
        array = EX_VAR(opline->result.var);
        if (IS_TMP_VAR != IS_UNUSED) {
                size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
-       } else {
-               size = 0;
-       }
-       ZVAL_ARR(array, zend_new_array(size));
-
-       if (IS_TMP_VAR != IS_UNUSED) {
+               ZVAL_ARR(array, zend_new_array(size));
                /* Explicitly initialize array as not-packed if flag is set */
                if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
                        zend_hash_real_init(Z_ARRVAL_P(array), 0);
                }
+               ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+       } else {
+               ZVAL_EMPTY_ARRAY(array);
+               ZEND_VM_NEXT_OPCODE();
        }
-
-       ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -14710,19 +14705,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_TMP_UNUSED_HAN
        array = EX_VAR(opline->result.var);
        if (IS_TMP_VAR != IS_UNUSED) {
                size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
-       } else {
-               size = 0;
-       }
-       ZVAL_ARR(array, zend_new_array(size));
-
-       if (IS_TMP_VAR != IS_UNUSED) {
+               ZVAL_ARR(array, zend_new_array(size));
                /* Explicitly initialize array as not-packed if flag is set */
                if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
                        zend_hash_real_init(Z_ARRVAL_P(array), 0);
                }
+               ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+       } else {
+               ZVAL_EMPTY_ARRAY(array);
+               ZEND_VM_NEXT_OPCODE();
        }
-
-       ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -15356,19 +15348,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_TMP_CV_HANDLER
        array = EX_VAR(opline->result.var);
        if (IS_TMP_VAR != IS_UNUSED) {
                size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
-       } else {
-               size = 0;
-       }
-       ZVAL_ARR(array, zend_new_array(size));
-
-       if (IS_TMP_VAR != IS_UNUSED) {
+               ZVAL_ARR(array, zend_new_array(size));
                /* Explicitly initialize array as not-packed if flag is set */
                if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
                        zend_hash_real_init(Z_ARRVAL_P(array), 0);
                }
+               ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+       } else {
+               ZVAL_EMPTY_ARRAY(array);
+               ZEND_VM_NEXT_OPCODE();
        }
-
-       ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -15902,19 +15891,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR_HAN
        array = EX_VAR(opline->result.var);
        if (IS_TMP_VAR != IS_UNUSED) {
                size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
-       } else {
-               size = 0;
-       }
-       ZVAL_ARR(array, zend_new_array(size));
-
-       if (IS_TMP_VAR != IS_UNUSED) {
+               ZVAL_ARR(array, zend_new_array(size));
                /* Explicitly initialize array as not-packed if flag is set */
                if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
                        zend_hash_real_init(Z_ARRVAL_P(array), 0);
                }
+               ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+       } else {
+               ZVAL_EMPTY_ARRAY(array);
+               ZEND_VM_NEXT_OPCODE();
        }
-
-       ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -16757,14 +16743,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPC
 
                        if (opline->extended_value == IS_ARRAY) {
                                if (Z_TYPE_P(expr) != IS_OBJECT) {
-                                       ZVAL_ARR(result, zend_new_array(8));
                                        if (Z_TYPE_P(expr) != IS_NULL) {
+                                               ZVAL_ARR(result, zend_new_array(8));
                                                expr = zend_hash_index_add_new(Z_ARRVAL_P(result), 0, expr);
                                                if (IS_VAR == IS_CONST) {
                                                        if (UNEXPECTED(Z_OPT_REFCOUNTED_P(expr))) Z_ADDREF_P(expr);
                                                } else {
                                                        if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr);
                                                }
+                                       } else {
+                                               ZVAL_EMPTY_ARRAY(result);
                                        }
                                } else {
                                        ZVAL_COPY_VALUE(result, expr);
@@ -20009,19 +19997,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_VAR_CONST_HAND
        array = EX_VAR(opline->result.var);
        if (IS_VAR != IS_UNUSED) {
                size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
-       } else {
-               size = 0;
-       }
-       ZVAL_ARR(array, zend_new_array(size));
-
-       if (IS_VAR != IS_UNUSED) {
+               ZVAL_ARR(array, zend_new_array(size));
                /* Explicitly initialize array as not-packed if flag is set */
                if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
                        zend_hash_real_init(Z_ARRVAL_P(array), 0);
                }
+               ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+       } else {
+               ZVAL_EMPTY_ARRAY(array);
+               ZEND_VM_NEXT_OPCODE();
        }
-
-       ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -21765,19 +21750,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_VAR_UNUSED_HAN
        array = EX_VAR(opline->result.var);
        if (IS_VAR != IS_UNUSED) {
                size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
-       } else {
-               size = 0;
-       }
-       ZVAL_ARR(array, zend_new_array(size));
-
-       if (IS_VAR != IS_UNUSED) {
+               ZVAL_ARR(array, zend_new_array(size));
                /* Explicitly initialize array as not-packed if flag is set */
                if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
                        zend_hash_real_init(Z_ARRVAL_P(array), 0);
                }
+               ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+       } else {
+               ZVAL_EMPTY_ARRAY(array);
+               ZEND_VM_NEXT_OPCODE();
        }
-
-       ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEPARATE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -24331,19 +24313,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_VAR_CV_HANDLER
        array = EX_VAR(opline->result.var);
        if (IS_VAR != IS_UNUSED) {
                size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
-       } else {
-               size = 0;
-       }
-       ZVAL_ARR(array, zend_new_array(size));
-
-       if (IS_VAR != IS_UNUSED) {
+               ZVAL_ARR(array, zend_new_array(size));
                /* Explicitly initialize array as not-packed if flag is set */
                if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
                        zend_hash_real_init(Z_ARRVAL_P(array), 0);
                }
+               ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+       } else {
+               ZVAL_EMPTY_ARRAY(array);
+               ZEND_VM_NEXT_OPCODE();
        }
-
-       ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -26847,19 +26826,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR_HAN
        array = EX_VAR(opline->result.var);
        if (IS_VAR != IS_UNUSED) {
                size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
-       } else {
-               size = 0;
-       }
-       ZVAL_ARR(array, zend_new_array(size));
-
-       if (IS_VAR != IS_UNUSED) {
+               ZVAL_ARR(array, zend_new_array(size));
                /* Explicitly initialize array as not-packed if flag is set */
                if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
                        zend_hash_real_init(Z_ARRVAL_P(array), 0);
                }
+               ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+       } else {
+               ZVAL_EMPTY_ARRAY(array);
+               ZEND_VM_NEXT_OPCODE();
        }
-
-       ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -29775,11 +29751,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FUNC_GET_ARGS_SPEC_UNUSED_UNUS
                result_size = arg_count;
        }
 
-       ht = zend_new_array(result_size);
-       ZVAL_ARR(EX_VAR(opline->result.var), ht);
-
        if (result_size) {
                uint32_t first_extra_arg = EX(func)->op_array.num_args;
+
+               ht = zend_new_array(result_size);
+               ZVAL_ARR(EX_VAR(opline->result.var), ht);
                zend_hash_real_init(ht, 1);
                ZEND_HASH_FILL_PACKED(ht) {
                        zval *p, *q;
@@ -29823,6 +29799,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FUNC_GET_ARGS_SPEC_UNUSED_UNUS
                        }
                } ZEND_HASH_FILL_END();
                ht->nNumOfElements = result_size;
+       } else {
+               ZVAL_EMPTY_ARRAY(EX_VAR(opline->result.var));
        }
        ZEND_VM_NEXT_OPCODE();
 }
@@ -34217,14 +34195,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CV_HANDLER(ZEND_OPCO
 
                        if (opline->extended_value == IS_ARRAY) {
                                if (Z_TYPE_P(expr) != IS_OBJECT) {
-                                       ZVAL_ARR(result, zend_new_array(8));
                                        if (Z_TYPE_P(expr) != IS_NULL) {
+                                               ZVAL_ARR(result, zend_new_array(8));
                                                expr = zend_hash_index_add_new(Z_ARRVAL_P(result), 0, expr);
                                                if (IS_CV == IS_CONST) {
                                                        if (UNEXPECTED(Z_OPT_REFCOUNTED_P(expr))) Z_ADDREF_P(expr);
                                                } else {
                                                        if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr);
                                                }
+                                       } else {
+                                               ZVAL_EMPTY_ARRAY(result);
                                        }
                                } else {
                                        ZVAL_COPY_VALUE(result, expr);
@@ -38224,19 +38204,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CV_CONST_HANDL
        array = EX_VAR(opline->result.var);
        if (IS_CV != IS_UNUSED) {
                size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
-       } else {
-               size = 0;
-       }
-       ZVAL_ARR(array, zend_new_array(size));
-
-       if (IS_CV != IS_UNUSED) {
+               ZVAL_ARR(array, zend_new_array(size));
                /* Explicitly initialize array as not-packed if flag is set */
                if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
                        zend_hash_real_init(Z_ARRVAL_P(array), 0);
                }
+               ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+       } else {
+               ZVAL_EMPTY_ARRAY(array);
+               ZEND_VM_NEXT_OPCODE();
        }
-
-       ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -40926,19 +40903,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CV_UNUSED_HAND
        array = EX_VAR(opline->result.var);
        if (IS_CV != IS_UNUSED) {
                size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
-       } else {
-               size = 0;
-       }
-       ZVAL_ARR(array, zend_new_array(size));
-
-       if (IS_CV != IS_UNUSED) {
+               ZVAL_ARR(array, zend_new_array(size));
                /* Explicitly initialize array as not-packed if flag is set */
                if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
                        zend_hash_real_init(Z_ARRVAL_P(array), 0);
                }
+               ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+       } else {
+               ZVAL_EMPTY_ARRAY(array);
+               ZEND_VM_NEXT_OPCODE();
        }
-
-       ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_CV_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -44766,19 +44740,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CV_CV_HANDLER(
        array = EX_VAR(opline->result.var);
        if (IS_CV != IS_UNUSED) {
                size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
-       } else {
-               size = 0;
-       }
-       ZVAL_ARR(array, zend_new_array(size));
-
-       if (IS_CV != IS_UNUSED) {
+               ZVAL_ARR(array, zend_new_array(size));
                /* Explicitly initialize array as not-packed if flag is set */
                if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
                        zend_hash_real_init(Z_ARRVAL_P(array), 0);
                }
+               ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+       } else {
+               ZVAL_EMPTY_ARRAY(array);
+               ZEND_VM_NEXT_OPCODE();
        }
-
-       ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -48377,19 +48348,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_HAND
        array = EX_VAR(opline->result.var);
        if (IS_CV != IS_UNUSED) {
                size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
-       } else {
-               size = 0;
-       }
-       ZVAL_ARR(array, zend_new_array(size));
-
-       if (IS_CV != IS_UNUSED) {
+               ZVAL_ARR(array, zend_new_array(size));
                /* Explicitly initialize array as not-packed if flag is set */
                if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
                        zend_hash_real_init(Z_ARRVAL_P(array), 0);
                }
+               ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+       } else {
+               ZVAL_EMPTY_ARRAY(array);
+               ZEND_VM_NEXT_OPCODE();
        }
-
-       ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
index 57d1c8796afbdae86e07f86ddcd45debfc27e665..f0b908ccf3fdc5fc4351166990e128bf3a9e4540 100644 (file)
@@ -134,8 +134,8 @@ static void dom_xpath_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs,
                                        xmlFree(str);
                                } else if (type == 2) {
                                        int j;
-                                       array_init(&fci.params[i]);
                                        if (obj->nodesetval && obj->nodesetval->nodeNr > 0) {
+                                               array_init(&fci.params[i]);
                                                for (j = 0; j < obj->nodesetval->nodeNr; j++) {
                                                        xmlNodePtr node = obj->nodesetval->nodeTab[j];
                                                        zval child;
@@ -161,6 +161,8 @@ static void dom_xpath_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs,
                                                        php_dom_create_object(node, &child, &intern->dom);
                                                        add_next_index_zval(&fci.params[i], &child);
                                                }
+                                       } else {
+                                               ZVAL_EMPTY_ARRAY(&fci.params[i]);
                                        }
                                }
                                break;
@@ -430,10 +432,9 @@ static void php_xpath_eval(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
                        int i;
                        xmlNodeSetPtr nodesetp;
 
-                       array_init(&retval);
-
-                       if (xpathobjp->type == XPATH_NODESET && NULL != (nodesetp = xpathobjp->nodesetval)) {
+                       if (xpathobjp->type == XPATH_NODESET && NULL != (nodesetp = xpathobjp->nodesetval) && nodesetp->nodeNr) {
 
+                               array_init(&retval);
                                for (i = 0; i < nodesetp->nodeNr; i++) {
                                        xmlNodePtr node = nodesetp->nodeTab[i];
                                        zval child;
@@ -459,6 +460,8 @@ static void php_xpath_eval(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
                                        php_dom_create_object(node, &child, &intern->dom);
                                        add_next_index_zval(&retval, &child);
                                }
+                       } else {
+                               ZVAL_EMPTY_ARRAY(&retval);
                        }
                        php_dom_create_interator(return_value, DOM_NODELIST);
                        nodeobj = Z_DOMOBJ_P(return_value);
index c355ae2ba41e6a6119a88a64d8ce9e1124352b52..74a1736894025c9dcc118b02ff64316196acb865 100644 (file)
@@ -1042,10 +1042,9 @@ static PHP_FUNCTION(libxml_get_errors)
 
        xmlErrorPtr error;
 
-       array_init(return_value);
-
        if (LIBXML(error_list)) {
 
+               array_init(return_value);
                error = zend_llist_get_first(LIBXML(error_list));
 
                while (error != NULL) {
@@ -1070,6 +1069,8 @@ static PHP_FUNCTION(libxml_get_errors)
 
                        error = zend_llist_get_next(LIBXML(error_list));
                }
+       } else {
+               ZVAL_EMPTY_ARRAY(return_value);
        }
 }
 /* }}} */
index 01fd345017ba94cf31ee2e543cf93c02caad7c01..7bb4304aff7d95accd02c5b953e7feabb5e363a6 100644 (file)
@@ -3136,10 +3136,11 @@ MBSTRING_API HashTable *php_mb_convert_encoding_recursive(HashTable *input, cons
                                break;
                        case IS_ARRAY:
                                chash = php_mb_convert_encoding_recursive(HASH_OF(entry), _to_encoding, _from_encodings);
-                               if (!chash) {
-                                       chash = zend_new_array(0);
+                               if (chash) {
+                                       ZVAL_ARR(&entry_tmp, chash);
+                               } else {
+                                       ZVAL_EMPTY_ARRAY(&entry_tmp);
                                }
-                               ZVAL_ARR(&entry_tmp, chash);
                                break;
                        case IS_OBJECT:
                        default:
index 3dba36317dd1c2136302f87bb8b64b549e28f1a9..6d4f648a7f87834b408f5aa3c47e4bcabf996e40 100644 (file)
@@ -423,11 +423,11 @@ PHP_FUNCTION(mysqli_error_list)
                return;
        }
        MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
-       array_init(return_value);
 #if defined(MYSQLI_USE_MYSQLND)
        if (mysql->mysql->data->error_info->error_list) {
                MYSQLND_ERROR_LIST_ELEMENT * message;
                zend_llist_position pos;
+               array_init(return_value);
                for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(mysql->mysql->data->error_info->error_list, &pos);
                         message;
                         message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(mysql->mysql->data->error_info->error_list, &pos))
@@ -439,15 +439,20 @@ PHP_FUNCTION(mysqli_error_list)
                        add_assoc_string_ex(&single_error, "error", sizeof("error") - 1, message->error);
                        add_next_index_zval(return_value, &single_error);
                }
+       } else {
+               ZVAL_EMPTY_ARRAY(return_value);
        }
 #else
        if (mysql_errno(mysql->mysql)) {
                zval single_error;
+               array_init(return_value);
                array_init(&single_error);
                add_assoc_long_ex(&single_error, "errno", sizeof("errno") - 1, mysql_errno(mysql->mysql));
                add_assoc_string_ex(&single_error, "sqlstate", sizeof("sqlstate") - 1, mysql_sqlstate(mysql->mysql));
                add_assoc_string_ex(&single_error, "error", sizeof("error") - 1, mysql_error(mysql->mysql));
                add_next_index_zval(return_value, &single_error);
+       } else {
+               ZVAL_EMPTY_ARRAY(return_value);
        }
 #endif
 }
@@ -464,11 +469,11 @@ PHP_FUNCTION(mysqli_stmt_error_list)
                return;
        }
        MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_INITIALIZED);
-       array_init(return_value);
 #if defined(MYSQLI_USE_MYSQLND)
        if (stmt->stmt && stmt->stmt->data && stmt->stmt->data->error_info->error_list) {
                MYSQLND_ERROR_LIST_ELEMENT * message;
                zend_llist_position pos;
+               array_init(return_value);
                for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(stmt->stmt->data->error_info->error_list, &pos);
                         message;
                         message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(stmt->stmt->data->error_info->error_list, &pos))
@@ -480,15 +485,20 @@ PHP_FUNCTION(mysqli_stmt_error_list)
                        add_assoc_string_ex(&single_error, "error", sizeof("error") - 1, message->error);
                        add_next_index_zval(return_value, &single_error);
                }
+       } else {
+               ZVAL_EMPTY_ARRAY(return_value);
        }
 #else
        if (mysql_stmt_errno(stmt->stmt)) {
                zval single_error;
+               array_init(return_value);
                array_init(&single_error);
                add_assoc_long_ex(&single_error, "errno", sizeof("errno") - 1, mysql_stmt_errno(stmt->stmt));
                add_assoc_string_ex(&single_error, "sqlstate", sizeof("sqlstate") - 1, mysql_stmt_sqlstate(stmt->stmt));
                add_assoc_string_ex(&single_error, "error", sizeof("error") - 1, mysql_stmt_error(stmt->stmt));
                add_next_index_zval(return_value, &single_error);
+       } else {
+               ZVAL_EMPTY_ARRAY(return_value);
        }
 #endif
 }
index 06a47360088813e1c13dba9820588f63e4d5bd9c..0b3858d1c3d7ee36f542f57533b09d72234680ce 100644 (file)
@@ -184,8 +184,8 @@ static zval *link_error_list_read(mysqli_object *obj, zval *retval)
 
        mysql = (MY_MYSQL *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;
 
-       array_init(retval);
        if (mysql) {
+               array_init(retval);
 #if defined(MYSQLI_USE_MYSQLND)
                if (mysql->mysql->data->error_info->error_list) {
                        MYSQLND_ERROR_LIST_ELEMENT * message;
@@ -212,6 +212,8 @@ static zval *link_error_list_read(mysqli_object *obj, zval *retval)
                        add_next_index_zval(retval, &single_error);
                }
 #endif
+       } else {
+               ZVAL_EMPTY_ARRAY(retval);
        }
 
        return retval;
@@ -374,8 +376,8 @@ static zval *stmt_error_list_read(mysqli_object *obj, zval *retval)
        CHECK_STATUS(MYSQLI_STATUS_INITIALIZED);
 
        stmt = (MY_STMT *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;
-       array_init(retval);
        if (stmt && stmt->stmt) {
+               array_init(retval);
 #if defined(MYSQLI_USE_MYSQLND)
                if (stmt->stmt->data && stmt->stmt->data->error_info->error_list) {
                        MYSQLND_ERROR_LIST_ELEMENT * message;
@@ -402,6 +404,8 @@ static zval *stmt_error_list_read(mysqli_object *obj, zval *retval)
                        add_next_index_zval(retval, &single_error);
                }
 #endif
+       } else {
+               ZVAL_EMPTY_ARRAY(retval);
        }
        return retval;
 }
index 6a199406862eb1b3b6011ecaabdb3469080be7b5..f8073e918605002bd0e4845e8956f08aaf1601b0 100644 (file)
@@ -1846,8 +1846,8 @@ ZEND_METHOD(reflection_function, getStaticVariables)
        GET_REFLECTION_OBJECT_PTR(fptr);
 
        /* Return an empty array in case no static variables exist */
-       array_init(return_value);
        if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.static_variables != NULL) {
+               array_init(return_value);
                if (GC_REFCOUNT(fptr->op_array.static_variables) > 1) {
                        if (!(GC_FLAGS(fptr->op_array.static_variables) & IS_ARRAY_IMMUTABLE)) {
                                GC_REFCOUNT(fptr->op_array.static_variables)--;
@@ -1860,6 +1860,8 @@ ZEND_METHOD(reflection_function, getStaticVariables)
                        }
                } ZEND_HASH_FOREACH_END();
                zend_hash_copy(Z_ARRVAL_P(return_value), fptr->op_array.static_variables, zval_add_ref);
+       } else {
+               ZVAL_EMPTY_ARRAY(return_value);
        }
 }
 /* }}} */
@@ -2046,6 +2048,11 @@ ZEND_METHOD(reflection_function, getParameters)
                num_args++;
        }
 
+       if (!num_args) {
+               ZVAL_EMPTY_ARRAY(return_value);
+               return;
+       }
+
        array_init(return_value);
        for (i = 0; i < num_args; i++) {
                zval parameter;
@@ -4917,17 +4924,17 @@ ZEND_METHOD(reflection_class, getInterfaces)
        }
        GET_REFLECTION_OBJECT_PTR(ce);
 
-       /* Return an empty array if this class implements no interfaces */
-       array_init(return_value);
-
        if (ce->num_interfaces) {
                uint32_t i;
 
+               array_init(return_value);
                for (i=0; i < ce->num_interfaces; i++) {
                        zval interface;
                        zend_reflection_class_factory(ce->interfaces[i], &interface);
                        zend_hash_update(Z_ARRVAL_P(return_value), ce->interfaces[i]->name, &interface);
                }
+       } else {
+               ZVAL_EMPTY_ARRAY(return_value);
        }
 }
 /* }}} */
@@ -4945,7 +4952,12 @@ ZEND_METHOD(reflection_class, getInterfaceNames)
        }
        GET_REFLECTION_OBJECT_PTR(ce);
 
-       /* Return an empty array if this class implements no interfaces */
+       if (!ce->num_interfaces) {
+               /* Return an empty array if this class implements no interfaces */
+               ZVAL_EMPTY_ARRAY(return_value);
+               return;
+       }
+
        array_init(return_value);
 
        for (i=0; i < ce->num_interfaces; i++) {
@@ -4967,6 +4979,11 @@ ZEND_METHOD(reflection_class, getTraits)
        }
        GET_REFLECTION_OBJECT_PTR(ce);
 
+       if (!ce->num_traits) {
+               ZVAL_EMPTY_ARRAY(return_value);
+               return;
+       }
+
        array_init(return_value);
 
        for (i=0; i < ce->num_traits; i++) {
@@ -4990,6 +5007,11 @@ ZEND_METHOD(reflection_class, getTraitNames)
        }
        GET_REFLECTION_OBJECT_PTR(ce);
 
+       if (!ce->num_traits) {
+               ZVAL_EMPTY_ARRAY(return_value);
+               return;
+       }
+
        array_init(return_value);
 
        for (i=0; i < ce->num_traits; i++) {
@@ -5010,10 +5032,11 @@ ZEND_METHOD(reflection_class, getTraitAliases)
        }
        GET_REFLECTION_OBJECT_PTR(ce);
 
-       array_init(return_value);
 
        if (ce->trait_aliases) {
                uint32_t i = 0;
+
+               array_init(return_value);
                while (ce->trait_aliases[i]) {
                        zend_string *mname;
                        zend_trait_method_reference *cur_ref = ce->trait_aliases[i]->trait_method;
@@ -5026,6 +5049,8 @@ ZEND_METHOD(reflection_class, getTraitAliases)
                        }
                        i++;
                }
+       } else {
+               ZVAL_EMPTY_ARRAY(return_value);
        }
 }
 /* }}} */
@@ -5961,15 +5986,15 @@ ZEND_METHOD(reflection_extension, getDependencies)
        }
        GET_REFLECTION_OBJECT_PTR(module);
 
-       array_init(return_value);
-
        dep = module->deps;
 
        if (!dep)
        {
+               ZVAL_EMPTY_ARRAY(return_value);
                return;
        }
 
+       array_init(return_value);
        while(dep->name) {
                zend_string *relation;
                char *rel_type;
index 92d180cf8b05643c6667d6ec9c8ff5173497d29c..748c5c5453a7debf2a2e9b70e19f6c5108c461a4 100644 (file)
@@ -1350,9 +1350,9 @@ SXE_METHOD(xpath)
 
        result = retval->nodesetval;
 
-       array_init(return_value);
-
        if (result != NULL) {
+               array_init(return_value);
+
                for (i = 0; i < result->nodeNr; ++i) {
                        nodeptr = result->nodeTab[i];
                        if (nodeptr->type == XML_TEXT_NODE || nodeptr->type == XML_ELEMENT_NODE || nodeptr->type == XML_ATTRIBUTE_NODE) {
@@ -1372,6 +1372,8 @@ SXE_METHOD(xpath)
                                add_next_index_zval(return_value, &value);
                        }
                }
+       } else {
+               ZVAL_EMPTY_ARRAY(return_value);
        }
 
        xmlXPathFreeObject(retval);
index 3dd5b0656f73c33c97ffa34773f672f997bbf5ba..46e627102bf7217a0dc9dcff7192f439438a0aad 100644 (file)
@@ -637,9 +637,10 @@ SPL_METHOD(SplFixedArray, toArray)
 
        intern = Z_SPLFIXEDARRAY_P(getThis());
 
-       array_init(return_value);
        if (intern->array.size > 0) {
                int i = 0;
+
+               array_init(return_value);
                for (; i < intern->array.size; i++) {
                        if (!Z_ISUNDEF(intern->array.elements[i])) {
                                zend_hash_index_update(Z_ARRVAL_P(return_value), i, &intern->array.elements[i]);
@@ -650,6 +651,8 @@ SPL_METHOD(SplFixedArray, toArray)
                                zend_hash_index_update(Z_ARRVAL_P(return_value), i, &EG(uninitialized_zval));
                        }
                }
+       } else {
+               ZVAL_EMPTY_ARRAY(return_value);
        }
 }
 /* }}} */
index cdd17bd1591e0bfb416e83a136a0a9e1b7c5bf5b..1b8f8e6e5f554184580117160190d8292799f31d 100644 (file)
@@ -676,7 +676,7 @@ PHP_METHOD(sqlite3, querySingle)
                        if (!entire_row) {
                                RETVAL_NULL();
                        } else {
-                               array_init(return_value);
+                               ZVAL_EMPTY_ARRAY(return_value);
                        }
                        break;
                }
index 3d4c153f12712a664687935038a6d9204d5934d8..2a0053ee8b541a4377c1cd0521a957108856c7ed 100644 (file)
@@ -2689,7 +2689,7 @@ PHP_FUNCTION(array_fill)
                        }
                }
        } else if (EXPECTED(num == 0)) {
-               array_init(return_value);
+               ZVAL_EMPTY_ARRAY(return_value);
                return;
        } else {
                php_error_docref(NULL, E_WARNING, "Number of elements can't be negative");
@@ -3545,7 +3545,7 @@ PHP_FUNCTION(array_slice)
 
        /* Clamp the offset.. */
        if (offset > num_in) {
-               array_init(return_value);
+               ZVAL_EMPTY_ARRAY(return_value);
                return;
        } else if (offset < 0 && (offset = (num_in + offset)) < 0) {
                offset = 0;
@@ -3559,7 +3559,7 @@ PHP_FUNCTION(array_slice)
        }
 
        if (length <= 0) {
-               array_init(return_value);
+               ZVAL_EMPTY_ARRAY(return_value);
                return;
        }
 
@@ -6316,12 +6316,12 @@ PHP_FUNCTION(array_combine)
                RETURN_FALSE;
        }
 
-       array_init_size(return_value, num_keys);
-
        if (!num_keys) {
+               ZVAL_EMPTY_ARRAY(return_value);
                return;
        }
 
+       array_init_size(return_value, num_keys);
        ZEND_HASH_FOREACH_VAL(keys, entry_keys) {
                while (1) {
                        if (pos_values >= values->nNumUsed) {
index b32379a06443a6b31a901be1e8f289b26a203258..d798b589fee1ef589d9f61116454deceaef6819a 100644 (file)
@@ -704,7 +704,7 @@ yy2:
        yych = *(YYMARKER = ++YYCURSOR);
        if (yych == ':') goto yy88;
 yy3:
-#line 1036 "ext/standard/var_unserializer.re"
+#line 1039 "ext/standard/var_unserializer.re"
        { return 0; }
 #line 710 "ext/standard/var_unserializer.c"
 yy4:
@@ -749,7 +749,7 @@ yy13:
        goto yy3;
 yy14:
        ++YYCURSOR;
-#line 1030 "ext/standard/var_unserializer.re"
+#line 1033 "ext/standard/var_unserializer.re"
        {
        /* this is the case where we have less data than planned */
        php_error_docref(NULL, E_NOTICE, "Unexpected end of serialized data");
@@ -779,7 +779,7 @@ yy19:
        yych = *++YYCURSOR;
        if (yych != '"') goto yy18;
        ++YYCURSOR;
-#line 878 "ext/standard/var_unserializer.re"
+#line 881 "ext/standard/var_unserializer.re"
        {
        size_t len, len2, len3, maxlen;
        zend_long elements;
@@ -946,7 +946,7 @@ yy25:
        yych = *++YYCURSOR;
        if (yych != '"') goto yy18;
        ++YYCURSOR;
-#line 867 "ext/standard/var_unserializer.re"
+#line 870 "ext/standard/var_unserializer.re"
        {
        zend_long elements;
     if (!var_hash) return 0;
@@ -983,11 +983,14 @@ yy31:
                return 0;
        }
 
-       array_init_size(rval, elements);
        if (elements) {
+               array_init_size(rval, elements);
                /* we can't convert from packed to hash during unserialization, because
                   reference to some zvals might be keept in var_hash (to support references) */
                zend_hash_real_init(Z_ARRVAL_P(rval), 0);
+       } else {
+               ZVAL_EMPTY_ARRAY(rval);
+               return finish_nested_data(UNSERIALIZE_PASSTHRU);
        }
 
        /* The array may contain references to itself, in which case we'll be modifying an
@@ -1002,7 +1005,7 @@ yy31:
 
        return finish_nested_data(UNSERIALIZE_PASSTHRU);
 }
-#line 1006 "ext/standard/var_unserializer.c"
+#line 1009 "ext/standard/var_unserializer.c"
 yy36:
        yych = *++YYCURSOR;
        if (yych <= '/') goto yy18;
@@ -1051,7 +1054,7 @@ yy37:
        ZVAL_STR(rval, str);
        return 1;
 }
-#line 1055 "ext/standard/var_unserializer.c"
+#line 1058 "ext/standard/var_unserializer.c"
 yy42:
        yych = *++YYCURSOR;
        if (yych <= '/') goto yy18;
@@ -1104,7 +1107,7 @@ yy43:
        }
        return 1;
 }
-#line 1108 "ext/standard/var_unserializer.c"
+#line 1111 "ext/standard/var_unserializer.c"
 yy48:
        yych = *++YYCURSOR;
        if (yych <= '/') {
@@ -1201,7 +1204,7 @@ use_double:
        ZVAL_DOUBLE(rval, zend_strtod((const char *)start + 2, NULL));
        return 1;
 }
-#line 1205 "ext/standard/var_unserializer.c"
+#line 1208 "ext/standard/var_unserializer.c"
 yy60:
        yych = *++YYCURSOR;
        if (yych <= ',') {
@@ -1265,7 +1268,7 @@ yy67:
 
        return 1;
 }
-#line 1269 "ext/standard/var_unserializer.c"
+#line 1272 "ext/standard/var_unserializer.c"
 yy70:
        yych = *++YYCURSOR;
        if (yych == 'N') goto yy67;
@@ -1318,7 +1321,7 @@ yy73:
        ZVAL_LONG(rval, parse_iv(start + 2));
        return 1;
 }
-#line 1322 "ext/standard/var_unserializer.c"
+#line 1325 "ext/standard/var_unserializer.c"
 yy77:
        yych = *++YYCURSOR;
        if (yych <= '/') goto yy18;
@@ -1332,7 +1335,7 @@ yy77:
        ZVAL_BOOL(rval, parse_iv(start + 2));
        return 1;
 }
-#line 1336 "ext/standard/var_unserializer.c"
+#line 1339 "ext/standard/var_unserializer.c"
 yy81:
        ++YYCURSOR;
 #line 702 "ext/standard/var_unserializer.re"
@@ -1341,7 +1344,7 @@ yy81:
        ZVAL_NULL(rval);
        return 1;
 }
-#line 1345 "ext/standard/var_unserializer.c"
+#line 1348 "ext/standard/var_unserializer.c"
 yy83:
        yych = *++YYCURSOR;
        if (yych <= '/') goto yy18;
@@ -1379,7 +1382,7 @@ yy84:
 
        return 1;
 }
-#line 1383 "ext/standard/var_unserializer.c"
+#line 1386 "ext/standard/var_unserializer.c"
 yy88:
        yych = *++YYCURSOR;
        if (yych <= '/') goto yy18;
@@ -1417,9 +1420,9 @@ yy89:
 
        return 1;
 }
-#line 1421 "ext/standard/var_unserializer.c"
+#line 1424 "ext/standard/var_unserializer.c"
 }
-#line 1038 "ext/standard/var_unserializer.re"
+#line 1041 "ext/standard/var_unserializer.re"
 
 
        return 0;
index 912d7be4c80c91df4c53351111cb4e5e59acbc87..3cf82b1e7adfb189642a02fb0871bda9a41a9acf 100644 (file)
@@ -844,11 +844,14 @@ use_double:
                return 0;
        }
 
-       array_init_size(rval, elements);
        if (elements) {
+               array_init_size(rval, elements);
                /* we can't convert from packed to hash during unserialization, because
                   reference to some zvals might be keept in var_hash (to support references) */
                zend_hash_real_init(Z_ARRVAL_P(rval), 0);
+       } else {
+               ZVAL_EMPTY_ARRAY(rval);
+               return finish_nested_data(UNSERIALIZE_PASSTHRU);
        }
 
        /* The array may contain references to itself, in which case we'll be modifying an
index 02c436e34058e9bfee5ac1016e432e7c0bc3d269..6fda147b5c53470df8354449c9900be5328a71e8 100644 (file)
@@ -252,8 +252,8 @@ static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int t
                                } else if (type == 2) {
                                        int j;
                                        dom_object *domintern = (dom_object *)intern->doc;
-                                       array_init(&args[i]);
                                        if (obj->nodesetval && obj->nodesetval->nodeNr > 0) {
+                                               array_init(&args[i]);
                                                for (j = 0; j < obj->nodesetval->nodeNr; j++) {
                                                        xmlNodePtr node = obj->nodesetval->nodeTab[j];
                                                        zval child;
@@ -282,6 +282,8 @@ static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int t
                                                        php_dom_create_object(node, &child, domintern);
                                                        add_next_index_zval(&args[i], &child);
                                                }
+                                       } else {
+                                               ZVAL_EMPTY_ARRAY(&args[i]);
                                        }
                                }
                                break;