Previous some places passed return_value_ptr only if the function
returned by reference. Now return_value_ptr is always set, even
for functions returning by-value.
This allows you to return zvals without copying their contents. For
this purpose two new macros RETVAL_ZVAL_FAST and RETURN_ZVAL_FAST
are added:
RETVAL_ZVAL_FAST(zv); /* Analog to RETVAL_ZVAL(zv, 1, 0) */
RETURN_ZVAL_FAST(zv); /* Analog to RETURN_ZVAL(zv, 1, 0) */
These macros behave similarly to the non-FAST versions with
copy=1 and dtor=0, with the difference that the FAST versions
will try return the zval without copying by utilizing return_value_ptr.
ZEND_NS_NAMED_FE(ns, zend_name, name, arg_info)
was resulting in a function declaration of:
ns\"zend_name"()
including the errant quotes.
This diff corrects that. There are currently no uses of ZEND_NS_NAMED_FE
in core and reason to believe that there are no uses in the wild either.
See https://wiki.php.net/rfc/zpp_improv
* cataphract/zpp_improv:
Update README.PARAMETER_PARSING_API
Export zend_parse_parameter()
Expose zend_parse_arg() as zend_parse_parameter()
zend_parse_parameters: allow ! for non pointers
Sometimes, one wants to accept several types for a given parameter. zpp
has special functionality for detecting the NULL type, since the NULL
type is frequently used to skip parameters.
However, supporting several types is otherwise very tedious. There are
many cases where this situation arises -- for instance one may want
to accept an arbitrary number of integer and expect them in an array,
but allow a bare integer too; one may want to accept something that
will be used as an array key (which can be either and int or a string);
one may want to accept integer and double numbers. A search for IS_LONG
reveals many situations where this need arises.
The usual solution is to fetch the argument with 'z'/'Z', check its
type, and then convert the argument, e.g. with convert_to_long_ex().
As explain in the last commit, this has different behavior and
generates inconsistency.
Another -- even more flawed strategy --, is to try zpp with a specific
format, forcing it quiet, and if it fails retrying with another form.
But because zpp changes the arguments directly in the stack (for
instance, using "l" converts the zval in the stack to IS_LONG), the
arguments may look different after the first zpp, leaving subtle bugs.
This commit also allows more complex scenarios, for instance where the
expected type of one parameter depends on other parameters.
. zend_function.pass_rest_by_reference is replaced by
ZEND_ACC_PASS_REST_BY_REFERENCE in zend_function.fn_flags
. zend_function.return_reference is replaced by ZEND_ACC_RETURN_REFERENCE
in zend_function.fn_flags
. zend_arg_info.required_num_args removed. it was needed only for internal
functions. Now the first arg_info for internal function (which has special
meaning) is represented by zend_internal_function_info structure.
. zend_op_array.size, size_var, size_literal, current_brk_cont,
backpatch_count moved into CG(context), because they are used only during
compilation.
. zend_op_array.start_op is moved into EG(start_op), because it's used
only for 'interactive' execution of single top-level op-array.
. zend_op_array.done_pass_two is replaced by ZEND_ACC_DONE_PASS_TWO in
zend_op_array.fn_flags.
. op_array.vars array is trimmed (reallocated) during pass_two.
. zend_class_entry.constants_updated is replaced by
ZEND_ACC_CONSTANTS_UPDATED in zend_class_entry.ce_flags
. the size of zend_class_entry is reduced by sharing the same memory space
by different information for internal and user classes.
See zend_class_inttry.info union.