mirror of
https://github.com/php/php-src.git
synced 2024-09-21 09:57:23 +00:00
- Improve ARG_INFO() macros to support supplying required_num_args
- Initial fix for foreach($o->mthd()->arr) crash (now leaks)
This commit is contained in:
parent
ab968b3d03
commit
7086634a0b
@ -1221,7 +1221,11 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, zend_function_entr
|
||||
internal_function->arg_info = ptr->arg_info+1;
|
||||
internal_function->num_args = ptr->num_args;
|
||||
/* Currently you cannot denote that the function can accept less arguments than num_args */
|
||||
internal_function->required_num_args = ptr->num_args;
|
||||
if (ptr->arg_info[0].required_num_args == -1) {
|
||||
internal_function->required_num_args = ptr->num_args;
|
||||
} else {
|
||||
internal_function->required_num_args = ptr->arg_info[0].required_num_args;
|
||||
}
|
||||
internal_function->pass_rest_by_reference = ptr->arg_info[0].pass_by_reference;
|
||||
internal_function->return_reference = ptr->arg_info[0].return_reference;
|
||||
} else {
|
||||
|
@ -57,14 +57,14 @@ typedef struct _zend_function_entry {
|
||||
ZEND_FENTRY(name, ZEND_FN(classname##_##alias), arg_info, flags)
|
||||
#define ZEND_ME_MAPPING(name, func_name, arg_types) ZEND_NAMED_FE(name, ZEND_FN(func_name), arg_types)
|
||||
|
||||
#define ZEND_ARG_INFO(pass_by_ref, name) { #name, sizeof(#name)-1, NULL, 0, 0, pass_by_ref, 0 },
|
||||
#define ZEND_ARG_PASS_INFO(pass_by_ref) { NULL, 0, NULL, 0, 0, pass_by_ref, 0 },
|
||||
#define ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null) { #name, sizeof(#name)-1, #classname, sizeof(#classname)-1, allow_null, pass_by_ref, 0 },
|
||||
#define ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, return_reference) \
|
||||
zend_arg_info name[] = { \
|
||||
{ NULL, 0, NULL, 0, 0, pass_rest_by_reference, return_reference },
|
||||
#define ZEND_ARG_INFO(pass_by_ref, name) { #name, sizeof(#name)-1, NULL, 0, 0, pass_by_ref, 0, 0 },
|
||||
#define ZEND_ARG_PASS_INFO(pass_by_ref) { NULL, 0, NULL, 0, 0, pass_by_ref, 0, 0 },
|
||||
#define ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null) { #name, sizeof(#name)-1, #classname, sizeof(#classname)-1, allow_null, pass_by_ref, 0, 0 },
|
||||
#define ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, return_reference, required_num_args) \
|
||||
zend_arg_info name[] = { \
|
||||
{ NULL, 0, NULL, 0, 0, pass_rest_by_reference, return_reference, required_num_args },
|
||||
#define ZEND_BEGIN_ARG_INFO(name, pass_rest_by_reference) \
|
||||
ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, ZEND_RETURN_REFERENCE_AGNOSTIC)
|
||||
ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, ZEND_RETURN_REFERENCE_AGNOSTIC, -1)
|
||||
#define ZEND_END_ARG_INFO() };
|
||||
|
||||
/* Name macros */
|
||||
|
@ -1713,7 +1713,7 @@ static zend_bool zend_do_perform_implementation_check(zend_function *fe)
|
||||
zend_uint i;
|
||||
zend_function *proto = fe->common.prototype;
|
||||
|
||||
if (!proto) {
|
||||
if (!proto || !proto->common.arg_info) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -3275,6 +3275,10 @@ void zend_do_foreach_begin(znode *foreach_token, znode *array, znode *open_brack
|
||||
is_variable = 1;
|
||||
}
|
||||
zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC);
|
||||
if (CG(active_op_array)->opcodes[CG(active_op_array)->last-1].opcode == ZEND_FETCH_OBJ_W) {
|
||||
/* FIXME: This will cause a leak, we have to unlock at the end of foreach() */
|
||||
CG(active_op_array)->opcodes[CG(active_op_array)->last-1].extended_value |= ZEND_FETCH_ADD_LOCK;
|
||||
}
|
||||
} else {
|
||||
is_variable = 0;
|
||||
}
|
||||
|
@ -141,6 +141,7 @@ typedef struct _zend_arg_info {
|
||||
zend_bool allow_null;
|
||||
zend_bool pass_by_reference;
|
||||
zend_bool return_reference;
|
||||
int required_num_args;
|
||||
} zend_arg_info;
|
||||
|
||||
struct _zend_op_array {
|
||||
|
@ -2040,6 +2040,9 @@ int zend_fetch_obj_r_handler(ZEND_OPCODE_HANDLER_ARGS)
|
||||
|
||||
int zend_fetch_obj_w_handler(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
if (opline->extended_value == ZEND_FETCH_ADD_LOCK) {
|
||||
PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
|
||||
}
|
||||
zend_fetch_property_address(&opline->result, &opline->op1, &opline->op2, EX(Ts), BP_VAR_W TSRMLS_CC);
|
||||
NEXT_OPCODE();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user