phalcon/cphalcon — pull request #1846 by sjinks (2014-01-17 11:33:42+00:00)
Title: phalcon_call_user_function() optimization

phalcon_call_user_function():
* make use of `zend_fcall_info_cache` to avoid expensive `zend_is_callable()` checks
* use `return_value_ptr` instead of `return_value` to enable return value optimization

Added `phalcon_call_func_aparams`:

```c
int phalcon_call_func_aparams(zval **return_value_ptr, const char *func_name, uint func_length, uint param_count, zval **params TSRMLS_DC)
```

Unlike `phalcon_call_func_params` it uses `zval**` (**a**rray) to pass the parameters and not variadic arguments (functions with variadic arguments cannot be inlined)

PHALCON_CALL_FUNCTION:
* use `phalcon_call_func_params` instead of `phalcon_call_func_params`
* drop `return_value` (this makes `phalcon_call_func_pXXX_ex` and `phalcon_call_func_pXXX` behave identically)
* drop `nparams` because the number of function arguments is calculated automatically
* do not pass extra `NULL` when the called function does not need any arguments
* use `RETURN_ON_FAILURE` macros

PHALCON_CALL_xxx macros:
* merged GNU and non-GNU versions of macros (for gcc-incompatible compilers `__builtin_constant_p(s)` is `#define`'d to 0)

Now that `PHALCON_CALL_FUNCTION()` macro can detect the number of function arguments automatically, we don't need `phalcon_call_func_pXXX`, `phalcon_return_call_func_pXXX`, `phalcon_call_func_pXXX_noret`, `phalcon_call_func_pXXX_ex` macros — they all have been replaced with `PHALCON_CALL_FUNCTION`

Other things:
* added `phalcon_return_call_function()` inline function which is used when the return value of the called function is passed directly into `return_value` and `return_value_ptr`. The function is useful when you need to do a cleanup on exception or call failure before returning;
* added `PHALCON_CALL_FUNCTIONW()` and `PHALCON_RETURN_CALL_FUNCTIONW()` which do the same as `PHALCON_CALL_FUNCTION()` and `PHALCON_RETURN_CALL_FUNCTION()` but do not restore the memory frame;
* added `__attribute__((warn_unused_result))` to all `phalcon_call_xxx` functions, as failure to check the result of the call may lead to unexpected things

How it breaks the API:

Used to be:

```c
PHALCON_INIT_VAR(result);
phalcon_call_func_p1(result, "function", parameter);
```

Now:

```c
PHALCON_OBS_VAR(result);
PHALCON_CALL_FUNCTION(&result, "function", parameter)
```

Advantages:
* less memory allocations (`return_value` is now allocated by Zend; used to be: allocated by Phalcon, desstroyed by Zend, reallocated by Zend)
* less code
* faster function calls due to `zend_fcall_info_cache`