diff options
author | Dmitry Stogov <dmitry@zend.com> | 2014-12-22 16:44:39 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2014-12-22 16:44:39 +0300 |
commit | 2646f7bcb98dcdd322ea21701c8bb101104ea619 (patch) | |
tree | 6cfa66ba666378de3c59759079e17f3245af0281 /Zend | |
parent | 2bc63e7b6d348e9210ec09facb4bedb6f4ab921a (diff) | |
download | php-git-2646f7bcb98dcdd322ea21701c8bb101104ea619.tar.gz |
Don't count variadic argument in zend_func.common.num_args. This allows faster CALL/RETURN code.
Diffstat (limited to 'Zend')
-rw-r--r-- | Zend/zend_API.c | 2 | ||||
-rw-r--r-- | Zend/zend_builtin_functions.c | 9 | ||||
-rw-r--r-- | Zend/zend_closures.c | 8 | ||||
-rw-r--r-- | Zend/zend_compile.c | 5 | ||||
-rw-r--r-- | Zend/zend_compile.h | 5 | ||||
-rw-r--r-- | Zend/zend_execute.c | 12 | ||||
-rw-r--r-- | Zend/zend_execute.h | 2 | ||||
-rw-r--r-- | Zend/zend_inheritance.c | 23 | ||||
-rw-r--r-- | Zend/zend_opcode.c | 7 |
9 files changed, 42 insertions, 31 deletions
diff --git a/Zend/zend_API.c b/Zend/zend_API.c index f6fcd356f5..4f19e48033 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -2206,6 +2206,8 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio } if (ptr->arg_info[ptr->num_args].is_variadic) { internal_function->fn_flags |= ZEND_ACC_VARIADIC; + /* Don't count the variadic argument */ + internal_function->num_args--; } } else { internal_function->arg_info = NULL; diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index f956f492b4..ed1a1c7a2c 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -443,9 +443,6 @@ ZEND_FUNCTION(func_get_arg) } first_extra_arg = ex->func->op_array.num_args; - if (ex->func->op_array.fn_flags & ZEND_ACC_VARIADIC) { - first_extra_arg--; - } if (requested_offset >= first_extra_arg && (ZEND_CALL_NUM_ARGS(ex) > first_extra_arg)) { arg = ZEND_CALL_VAR_NUM(ex, ex->func->op_array.last_var + ex->func->op_array.T) + (requested_offset - first_extra_arg); } else { @@ -476,9 +473,6 @@ ZEND_FUNCTION(func_get_args) Bucket *q; first_extra_arg = ex->func->op_array.num_args; - if (ex->func->op_array.fn_flags & ZEND_ACC_VARIADIC) { - first_extra_arg--; - } zend_hash_real_init(Z_ARRVAL_P(return_value), 1); i = 0; q = Z_ARRVAL_P(return_value)->arData; @@ -2136,9 +2130,6 @@ static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array) / if (call->func->type == ZEND_USER_FUNCTION) { uint32_t first_extra_arg = call->func->op_array.num_args; - if (call->func->op_array.fn_flags & ZEND_ACC_VARIADIC) { - first_extra_arg--; - } if (ZEND_CALL_NUM_ARGS(call) > first_extra_arg) { while (i < first_extra_arg) { if (Z_REFCOUNTED_P(p)) Z_ADDREF_P(p); diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index 0b0ae2e4d4..51585fec91 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -361,11 +361,15 @@ static HashTable *zend_closure_get_debug_info(zval *object, int *is_temp) /* {{{ } if (arg_info) { - uint32_t i, required = closure->func.common.required_num_args; + uint32_t i, num_args, required = closure->func.common.required_num_args; array_init(&val); - for (i = 0; i < closure->func.common.num_args; i++) { + num_args = closure->func.common.num_args; + if (closure->func.common.fn_flags & ZEND_ACC_VARIADIC) { + num_args++; + } + for (i = 0; i < num_args; i++) { zend_string *name; zval info; if (arg_info->name) { diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index c159fcc6e1..7c323def84 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3884,6 +3884,11 @@ void zend_compile_params(zend_ast *ast) /* {{{ */ /* These are assigned at the end to avoid unitialized memory in case of an error */ op_array->num_args = list->children; op_array->arg_info = arg_infos; + + /* Don't count the variadic argument */ + if (op_array->fn_flags & ZEND_ACC_VARIADIC) { + op_array->num_args--; + } } /* }}} */ diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 9b0bfda273..541c5f06fb 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -835,13 +835,14 @@ static zend_always_inline int zend_check_arg_send_type(const zend_function *zf, if (UNEXPECTED(zf->common.arg_info == NULL)) { return 0; } - if (UNEXPECTED(arg_num > zf->common.num_args)) { + arg_num--; + if (UNEXPECTED(arg_num >= zf->common.num_args)) { if (EXPECTED((zf->common.fn_flags & ZEND_ACC_VARIADIC) == 0)) { return 0; } arg_num = zf->common.num_args; } - return UNEXPECTED((zf->common.arg_info[arg_num-1].pass_by_reference & mask) != 0); + return UNEXPECTED((zf->common.arg_info[arg_num].pass_by_reference & mask) != 0); } #define ARG_MUST_BE_SENT_BY_REF(zf, arg_num) \ diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index f7dc69c099..aaa25cabca 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -622,7 +622,7 @@ static void zend_verify_internal_arg_type(zend_function *zf, uint32_t arg_num, z if (EXPECTED(arg_num <= zf->internal_function.num_args)) { cur_arg_info = &zf->internal_function.arg_info[arg_num-1]; } else if (zf->internal_function.fn_flags & ZEND_ACC_VARIADIC) { - cur_arg_info = &zf->internal_function.arg_info[zf->internal_function.num_args-1]; + cur_arg_info = &zf->internal_function.arg_info[zf->internal_function.num_args]; } else { return; } @@ -671,7 +671,7 @@ static void zend_verify_arg_type(zend_function *zf, uint32_t arg_num, zval *arg, if (EXPECTED(arg_num <= zf->common.num_args)) { cur_arg_info = &zf->common.arg_info[arg_num-1]; } else if (zf->common.fn_flags & ZEND_ACC_VARIADIC) { - cur_arg_info = &zf->common.arg_info[zf->common.num_args-1]; + cur_arg_info = &zf->common.arg_info[zf->common.num_args]; } else { return; } @@ -720,7 +720,7 @@ static inline int zend_verify_missing_arg_type(zend_function *zf, uint32_t arg_n if (EXPECTED(arg_num <= zf->common.num_args)) { cur_arg_info = &zf->common.arg_info[arg_num-1]; } else if (zf->common.fn_flags & ZEND_ACC_VARIADIC) { - cur_arg_info = &zf->common.arg_info[zf->common.num_args-1]; + cur_arg_info = &zf->common.arg_info[zf->common.num_args]; } else { return 1; } @@ -1626,9 +1626,6 @@ static zend_always_inline void i_init_func_execute_data(zend_execute_data *execu /* Handle arguments */ first_extra_arg = op_array->num_args; - if (UNEXPECTED((op_array->fn_flags & ZEND_ACC_VARIADIC) != 0)) { - first_extra_arg--; - } num_args = EX_NUM_ARGS(); if (UNEXPECTED(num_args > first_extra_arg)) { zval *end, *src, *dst; @@ -1721,9 +1718,6 @@ static zend_always_inline void i_init_execute_data(zend_execute_data *execute_da /* Handle arguments */ first_extra_arg = op_array->num_args; - if (UNEXPECTED((op_array->fn_flags & ZEND_ACC_VARIADIC) != 0)) { - first_extra_arg--; - } num_args = EX_NUM_ARGS(); if (UNEXPECTED(num_args > first_extra_arg)) { zval *end, *src, *dst; diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index 0d58c6195d..9197e4c9e5 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -176,7 +176,7 @@ static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame(uint3 static zend_always_inline void zend_vm_stack_free_extra_args(zend_execute_data *call) { - uint32_t first_extra_arg = call->func->op_array.num_args - ((call->func->common.fn_flags & ZEND_ACC_VARIADIC) != 0); + uint32_t first_extra_arg = call->func->op_array.num_args; if (UNEXPECTED(ZEND_CALL_NUM_ARGS(call) > first_extra_arg)) { zval *end = ZEND_CALL_VAR_NUM(call, call->func->op_array.last_var + call->func->op_array.T); diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index 5f7b17277b..b7730be8f0 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -261,9 +261,14 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c * go through all the parameters of the function and not just those present in the * prototype. */ num_args = proto->common.num_args; - if ((proto->common.fn_flags & ZEND_ACC_VARIADIC) - && fe->common.num_args > proto->common.num_args) { - num_args = fe->common.num_args; + if (proto->common.fn_flags & ZEND_ACC_VARIADIC) { + num_args++; + if (fe->common.num_args >= proto->common.num_args) { + num_args = fe->common.num_args; + if (fe->common.fn_flags & ZEND_ACC_VARIADIC) { + num_args++; + } + } } for (i = 0; i < num_args; i++) { @@ -273,7 +278,7 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c if (i < proto->common.num_args) { proto_arg_info = &proto->common.arg_info[i]; } else { - proto_arg_info = &proto->common.arg_info[proto->common.num_args-1]; + proto_arg_info = &proto->common.arg_info[proto->common.num_args]; } if (ZEND_LOG_XOR(fe_arg_info->class_name, proto_arg_info->class_name)) { @@ -380,11 +385,15 @@ static zend_string *zend_get_function_declaration(zend_function *fptr) /* {{{ */ smart_str_appendc(&str, '('); if (fptr->common.arg_info) { - uint32_t i, required; + uint32_t i, num_args, required; zend_arg_info *arg_info = fptr->common.arg_info; required = fptr->common.required_num_args; - for (i = 0; i < fptr->common.num_args;) { + num_args = fptr->common.num_args; + if (fptr->common.fn_flags & ZEND_ACC_VARIADIC) { + num_args++; + } + for (i = 0; i < num_args;) { if (arg_info->class_name) { const char *class_name; size_t class_name_len; @@ -486,7 +495,7 @@ static zend_string *zend_get_function_declaration(zend_function *fptr) /* {{{ */ } } - if (++i < fptr->common.num_args) { + if (++i < num_args) { smart_str_appends(&str, ", "); } arg_info++; diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 82c87c5cd2..fc29e2aadc 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -368,7 +368,12 @@ ZEND_API void destroy_op_array(zend_op_array *op_array) zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_dtor_handler, op_array); } if (op_array->arg_info) { - for (i=0; i<op_array->num_args; i++) { + uint32_t num_args = op_array->num_args; + + if (op_array->fn_flags & ZEND_ACC_VARIADIC) { + num_args++; + } + for (i = 0; i < num_args; i++) { zend_string_release(op_array->arg_info[i].name); if (op_array->arg_info[i].class_name) { zend_string_release(op_array->arg_info[i].class_name); |