--- /dev/null
+--TEST--
+call_user_func_array() passes value to prefer-ref arg if element wasn't a reference
+--FILE--
+<?php
+
+namespace {
+ call_user_func_array('array_multisort', [[3, 2, 1]]);
+
+ $args = [[3, 2, 1]];
+ call_user_func_array('array_multisort', $args);
+ var_dump($args);
+ unset($args);
+}
+
+namespace Foo {
+ call_user_func_array('array_multisort', [[3, 2, 1]]);
+
+ $args = [[3, 2, 1]];
+ call_user_func_array('array_multisort', $args);
+ var_dump($args);
+ unset($args);
+}
+
+?>
+--EXPECT--
+array(1) {
+ [0]=>
+ array(3) {
+ [0]=>
+ int(3)
+ [1]=>
+ int(2)
+ [2]=>
+ int(1)
+ }
+}
+array(1) {
+ [0]=>
+ array(3) {
+ [0]=>
+ int(3)
+ [1]=>
+ int(2)
+ [2]=>
+ int(1)
+ }
+}
ht = Z_ARRVAL_P(args);
zend_vm_stack_extend_call_frame(&EX(call), 0, zend_hash_num_elements(ht));
- if (OP1_TYPE != IS_CONST && OP1_TYPE != IS_TMP_VAR && Z_IMMUTABLE_P(args)) {
- int separate = 0;
-
- /* check if any of arguments are going to be passed by reference */
- for (arg_num = 0; arg_num < zend_hash_num_elements(ht); arg_num++) {
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num + 1)) {
- separate = 1;
- break;
- }
- }
- if (separate) {
- zval_copy_ctor(args);
- ht = Z_ARRVAL_P(args);
- }
- }
-
arg_num = 1;
param = ZEND_CALL_ARG(EX(call), 1);
ZEND_HASH_FOREACH_VAL(ht, arg) {
break;
}
-
- ZVAL_NEW_REF(arg, arg);
}
- Z_ADDREF_P(arg);
- } else{
+ } else {
if (Z_ISREF_P(arg) &&
!(EX(call)->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
/* don't separate references for __call */
arg = Z_REFVAL_P(arg);
}
- if (Z_OPT_REFCOUNTED_P(arg)) {
- Z_ADDREF_P(arg);
- }
}
- ZVAL_COPY_VALUE(param, arg);
+ ZVAL_COPY(param, arg);
ZEND_CALL_NUM_ARGS(EX(call))++;
arg_num++;
param++;
ht = Z_ARRVAL_P(args);
zend_vm_stack_extend_call_frame(&EX(call), 0, zend_hash_num_elements(ht));
- if (opline->op1_type != IS_CONST && opline->op1_type != IS_TMP_VAR && Z_IMMUTABLE_P(args)) {
- int separate = 0;
-
- /* check if any of arguments are going to be passed by reference */
- for (arg_num = 0; arg_num < zend_hash_num_elements(ht); arg_num++) {
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num + 1)) {
- separate = 1;
- break;
- }
- }
- if (separate) {
- zval_copy_ctor(args);
- ht = Z_ARRVAL_P(args);
- }
- }
-
arg_num = 1;
param = ZEND_CALL_ARG(EX(call), 1);
ZEND_HASH_FOREACH_VAL(ht, arg) {
break;
}
-
- ZVAL_NEW_REF(arg, arg);
}
- Z_ADDREF_P(arg);
- } else{
+ } else {
if (Z_ISREF_P(arg) &&
!(EX(call)->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
/* don't separate references for __call */
arg = Z_REFVAL_P(arg);
}
- if (Z_OPT_REFCOUNTED_P(arg)) {
- Z_ADDREF_P(arg);
- }
}
- ZVAL_COPY_VALUE(param, arg);
+ ZVAL_COPY(param, arg);
ZEND_CALL_NUM_ARGS(EX(call))++;
arg_num++;
param++;