summaryrefslogtreecommitdiff
path: root/Zend/zend_execute_API.c
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2015-04-03 16:35:06 +0300
committerDmitry Stogov <dmitry@zend.com>2015-04-03 16:35:06 +0300
commitdcaa79546b25723136e37589e56fc602a503db12 (patch)
treedbe4afa0a62096359e9d265a1e591a01e5513c1c /Zend/zend_execute_API.c
parent75551c3f59bafce69a6b54434b836f49ed5546f5 (diff)
downloadphp-git-dcaa79546b25723136e37589e56fc602a503db12.tar.gz
Don't relay on reference-counter when parameter expected to be a reference, but value given.
Diffstat (limited to 'Zend/zend_execute_API.c')
-rw-r--r--Zend/zend_execute_API.c53
1 files changed, 14 insertions, 39 deletions
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index b703f18915..d37c2cd1d8 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -670,7 +670,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) /
zend_fcall_info_cache fci_cache_local;
zend_function *func;
zend_class_entry *orig_scope;
- zval tmp;
ZVAL_UNDEF(fci->retval);
@@ -775,26 +774,10 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) /
for (i=0; i<fci->param_count; i++) {
zval *param;
+ zval *arg = &fci->params[i];
if (ARG_SHOULD_BE_SENT_BY_REF(func, i + 1)) {
- // TODO: Scalar values don't have reference counters anymore.
- // They are assumed to be 1, and they may be easily passed by
- // reference now. However, previously scalars with refcount==1
- // might be passed and with refcount>1 might not. We can support
- // only single behavior ???
-#if 0
- if (Z_REFCOUNTED(fci->params[i]) &&
- // This solution breaks the following test (omit warning message) ???
- // Zend/tests/bug61273.phpt
- // ext/reflection/tests/bug42976.phpt
- // ext/standard/tests/general_functions/call_user_func_array_variation_001.phpt
-#else
- if (!Z_REFCOUNTED(fci->params[i]) ||
- // This solution breaks the following test (emit warning message) ???
- // ext/pdo_sqlite/tests/pdo_005.phpt
-#endif
- (!Z_ISREF(fci->params[i]) && Z_REFCOUNT(fci->params[i]) > 1)) {
-
+ if (UNEXPECTED(!Z_ISREF_P(arg))) {
if (fci->no_separation &&
!ARG_MAY_BE_SENT_BY_REF(func, i + 1)) {
if (i) {
@@ -815,29 +798,21 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) /
return FAILURE;
}
- if (Z_REFCOUNTED(fci->params[i])) {
- Z_DELREF(fci->params[i]);
- }
- ZVAL_DUP(&tmp, &fci->params[i]);
- ZVAL_NEW_REF(&fci->params[i], &tmp);
- Z_ADDREF(fci->params[i]);
- } else if (!Z_ISREF(fci->params[i])) {
- ZVAL_NEW_REF(&fci->params[i], &fci->params[i]);
- Z_ADDREF(fci->params[i]);
- } else if (Z_REFCOUNTED(fci->params[i])) {
- Z_ADDREF(fci->params[i]);
+ ZVAL_NEW_REF(arg, arg);
}
- param = ZEND_CALL_ARG(call, i+1);
- ZVAL_COPY_VALUE(param, &fci->params[i]);
- } else if (Z_ISREF(fci->params[i]) &&
- /* don't separate references for __call */
- (func->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) == 0 ) {
- param = ZEND_CALL_ARG(call, i+1);
- ZVAL_DUP(param, Z_REFVAL(fci->params[i]));
+ Z_ADDREF_P(arg);
} else {
- param = ZEND_CALL_ARG(call, i+1);
- ZVAL_COPY(param, &fci->params[i]);
+ if (Z_ISREF_P(arg) &&
+ (func->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) == 0 ) {
+ /* don't separate references for __call */
+ arg = Z_REFVAL_P(arg);
+ }
+ if (Z_OPT_REFCOUNTED_P(arg)) {
+ Z_ADDREF_P(arg);
+ }
}
+ param = ZEND_CALL_ARG(call, i+1);
+ ZVAL_COPY_VALUE(param, arg);
}
EG(scope) = calling_scope;