summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
authorZeev Suraski <zeev@php.net>1999-08-06 15:24:10 +0000
committerZeev Suraski <zeev@php.net>1999-08-06 15:24:10 +0000
commitf95edc016b090bfe6494d5cffdd37315b7bb9d7c (patch)
treea2c02db4ac41a45c96f66d79489dbaf0b95876d4 /Zend
parent65ee58da41db12d1dfca573eb813af18e6787938 (diff)
downloadphp-git-f95edc016b090bfe6494d5cffdd37315b7bb9d7c.tar.gz
Introduce call_user_func_ex()
Diffstat (limited to 'Zend')
-rw-r--r--Zend/zend_API.h1
-rw-r--r--Zend/zend_execute_API.c49
2 files changed, 45 insertions, 5 deletions
diff --git a/Zend/zend_API.h b/Zend/zend_API.h
index c8ba5e6715..2c0c69e831 100644
--- a/Zend/zend_API.h
+++ b/Zend/zend_API.h
@@ -112,6 +112,7 @@ ZEND_API int add_get_index_string(zval *arg, uint idx, char *str, void **dest, i
ZEND_API int add_get_index_stringl(zval *arg, uint idx, char *str, uint length, void **dest, int duplicate);
ZEND_API int call_user_function(HashTable *function_table, zval *object, zval *function_name, zval *retval, int param_count, zval *params[]);
+ZEND_API int call_user_function_ex(HashTable *function_table, zval *object, zval *function_name, zval *retval, int param_count, zval **params[], int no_separation);
ZEND_API int add_property_long(zval *arg, char *key, long l);
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index 586249a345..267f566eb8 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -288,8 +288,24 @@ ZEND_API void zval_update_constant(zval *p)
}
}
+
int call_user_function(HashTable *function_table, zval *object, zval *function_name, zval *retval, int param_count, zval *params[])
{
+ zval ***params_array = (zval ***) emalloc(sizeof(zval **)*param_count);
+ int i;
+ int ex_retval;
+
+ for (i=0; i<param_count; i++) {
+ params_array[i] = &params[i];
+ }
+ ex_retval = call_user_function_ex(function_table, object, function_name, retval, param_count, params_array, 1);
+ efree(params_array);
+ return ex_retval;
+}
+
+
+int call_user_function_ex(HashTable *function_table, zval *object, zval *function_name, zval *retval, int param_count, zval **params[], int no_separation)
+{
int i;
zval *original_return_value;
HashTable *calling_symbol_table;
@@ -312,14 +328,37 @@ int call_user_function(HashTable *function_table, zval *object, zval *function_n
return FAILURE;
}
-
for (i=0; i<param_count; i++) {
zval *param;
- param = (zval *) emalloc(sizeof(zval));
- *param = *(params[i]);
- INIT_PZVAL(param);
- zval_copy_ctor(param);
+ if (function_state.function->common.arg_types
+ && i<function_state.function->common.arg_types[0]
+ && function_state.function->common.arg_types[i+1]==BYREF_FORCE
+ && !PZVAL_IS_REF(*params[i])) {
+ if ((*params[i])->refcount>1) {
+ zval *new_zval;
+
+ if (no_separation) {
+ return FAILURE;
+ }
+ new_zval = (zval *) emalloc(sizeof(zval));
+ *new_zval = **params[i];
+ new_zval->refcount = 1;
+ new_zval->EA.locks = 0;
+ (*params[i])->refcount--;
+ *params[i] = new_zval;
+ }
+ (*params[i])->refcount++;
+ (*params[i])->EA.is_ref = 1;
+ param = *params[i];
+ } else if (*params[i] != &EG(uninitialized_zval)) {
+ (*params[i])->refcount++;
+ param = *params[i];
+ } else {
+ param = (zval *) emalloc(sizeof(zval));
+ *param = **(params[i]);
+ INIT_PZVAL(param);
+ }
zend_ptr_stack_push(&EG(argument_stack), param);
}