]> granicus.if.org Git - php/commitdiff
Added support for overloaded functions (e.g. COM) in call_user_func().
authorDmitry Stogov <dmitry@php.net>
Sat, 26 Jul 2008 17:01:40 +0000 (17:01 +0000)
committerDmitry Stogov <dmitry@php.net>
Sat, 26 Jul 2008 17:01:40 +0000 (17:01 +0000)
Zend/zend_execute_API.c

index 360e403b1c1af3b25e41df34f174418a19d35bcc..561bbdcf49fb544a6f0d3913fee8686b726c8d3b 100644 (file)
@@ -886,7 +886,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
                EG(active_op_array) = original_op_array;
                EG(return_value_ptr_ptr)=original_return_value;
                EG(opline_ptr) = original_opline_ptr;
-       } else {
+       } else if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) {
                int call_via_handler = (EX(function_state).function->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0;
 
                ALLOC_INIT_ZVAL(*fci->retval_ptr_ptr);
@@ -909,6 +909,26 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
                        /* We must re-initialize function again */
                        fci_cache->initialized = 0;
                }
+       } else { /* ZEND_OVERLOADED_FUNCTION */
+
+               ALLOC_INIT_ZVAL(*fci->retval_ptr_ptr);
+
+                       /* Not sure what should be done here if it's a static method */
+               if (fci->object_pp) {
+                       Z_OBJ_HT_PP(fci->object_pp)->call_method(EX(function_state).function->common.function_name, fci->param_count, *fci->retval_ptr_ptr, fci->retval_ptr_ptr, *fci->object_pp, 1 TSRMLS_CC);
+               } else {
+                       zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
+               }
+
+               if (EX(function_state).function->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
+                       efree(EX(function_state).function->common.function_name);
+               }
+               efree(EX(function_state).function);
+
+               if (EG(exception) && fci->retval_ptr_ptr) {
+                       zval_ptr_dtor(fci->retval_ptr_ptr);
+                       *fci->retval_ptr_ptr = NULL;
+               }
        }
        zend_vm_stack_clear_multiple(TSRMLS_C);