summaryrefslogtreecommitdiff
path: root/Zend/zend_API.c
diff options
context:
space:
mode:
authorMarcus Boerger <helly@php.net>2006-06-07 09:43:54 +0000
committerMarcus Boerger <helly@php.net>2006-06-07 09:43:54 +0000
commit64c353ab79e3a49ae2aba533d353d4a93fe4b099 (patch)
treec462411f5fbb0d02143964910563642c93c1b9a3 /Zend/zend_API.c
parent1f93575c88fff9e05e1904ba02d0975ab33f0c67 (diff)
downloadphp-git-64c353ab79e3a49ae2aba533d353d4a93fe4b099.tar.gz
- MFH zend_fcall_info_*() and parameter parsing option 'f'
# Right now i see this as the best option but we might shuffle code around # later if someone comes up with a better solution.
Diffstat (limited to 'Zend/zend_API.c')
-rw-r--r--Zend/zend_API.c106
1 files changed, 106 insertions, 0 deletions
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index 31faa25e7a..57892f3b99 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -566,6 +566,22 @@ static char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, char **sp
}
break;
+ case 'f':
+ {
+ zend_fcall_info *fci = va_arg(*va, zend_fcall_info *);
+ zend_fcall_info_cache *fcc = va_arg(*va, zend_fcall_info_cache *);
+
+ if (zend_fcall_info_init(*arg, fci, fcc TSRMLS_CC) == SUCCESS) {
+ break;
+ } else if (return_null) {
+ fci->size = 0;
+ fcc->initialized = 0;
+ break;
+ } else {
+ return "function";
+ }
+ }
+
case 'z':
{
zval **p = va_arg(*va, zval **);
@@ -2309,6 +2325,96 @@ ZEND_API zend_bool zend_make_callable(zval *callable, char **callable_name TSRML
}
+ZEND_API int zend_fcall_info_init(zval *callable, zend_fcall_info *fci, zend_fcall_info_cache *fcc TSRMLS_DC)
+{
+ zend_class_entry *ce;
+ zend_function *func;
+ zval **obj;
+
+ if (!zend_is_callable_ex(callable, IS_CALLABLE_STRICT, NULL, NULL, &ce, &func, &obj TSRMLS_CC)) {
+ return FAILURE;
+ }
+
+ fci->size = sizeof(*fci);
+ fci->function_table = ce ? &ce->function_table : EG(function_table);
+ fci->object_pp = obj;
+ fci->function_name = NULL;
+ fci->retval_ptr_ptr = NULL;
+ fci->param_count = 0;
+ fci->params = NULL;
+ fci->no_separation = 1;
+ fci->symbol_table = NULL;
+
+ fcc->initialized = 1;
+ fcc->function_handler = func;
+ fcc->calling_scope = ce;
+ fcc->object_pp = obj;
+
+ return SUCCESS;
+}
+
+
+ZEND_API int zend_fcall_info_args(zend_fcall_info *fci, zval *args TSRMLS_DC)
+{
+ HashPosition pos;
+ zval **arg, ***params;
+
+ if (fci->params) {
+ while (fci->param_count) {
+ zval_ptr_dtor(fci->params[--fci->param_count]);
+ }
+ efree(fci->params);
+ }
+ fci->params = NULL;
+ fci->param_count = 0;
+
+ if (!args) {
+ return SUCCESS;
+ }
+
+ if (Z_TYPE_P(args) != IS_ARRAY) {
+ return FAILURE;
+ }
+
+ fci->param_count = zend_hash_num_elements(Z_ARRVAL_P(args));
+ fci->params = params = (zval***)safe_emalloc(sizeof(zval**), fci->param_count, 0);
+
+ zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(args), &pos);
+
+ while (zend_hash_get_current_data_ex(Z_ARRVAL_P(args), (void **) &arg, &pos) == SUCCESS) {
+ *params++ = arg;
+ (*arg)->refcount++;
+ zend_hash_move_forward_ex(Z_ARRVAL_P(args), &pos);
+ }
+ return SUCCESS;
+}
+
+
+ZEND_API int zend_fcall_info_call(zend_fcall_info *fci, zend_fcall_info_cache *fcc, zval **retval_ptr_ptr, zval *args TSRMLS_DC)
+{
+ zval *retval, ***org_params;
+ int result, org_count;
+
+ fci->retval_ptr_ptr = retval_ptr_ptr ? retval_ptr_ptr : &retval;
+ if (args) {
+ org_params = fci->params;
+ org_count = fci->param_count;
+ zend_fcall_info_args(fci, args TSRMLS_CC);
+ }
+ result = zend_call_function(fci, fcc TSRMLS_CC);
+
+ if (!retval_ptr_ptr && retval) {
+ zval_ptr_dtor(&retval);
+ }
+ if (args) {
+ zend_fcall_info_args(fci, NULL TSRMLS_CC);
+ fci->params = org_params;
+ fci->param_count = org_count;
+ }
+ return result;
+}
+
+
ZEND_API char *zend_get_module_version(char *module_name)
{
zend_module_entry *module;