summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2014-12-22 16:44:39 +0300
committerDmitry Stogov <dmitry@zend.com>2014-12-22 16:44:39 +0300
commit2646f7bcb98dcdd322ea21701c8bb101104ea619 (patch)
tree6cfa66ba666378de3c59759079e17f3245af0281 /Zend
parent2bc63e7b6d348e9210ec09facb4bedb6f4ab921a (diff)
downloadphp-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.c2
-rw-r--r--Zend/zend_builtin_functions.c9
-rw-r--r--Zend/zend_closures.c8
-rw-r--r--Zend/zend_compile.c5
-rw-r--r--Zend/zend_compile.h5
-rw-r--r--Zend/zend_execute.c12
-rw-r--r--Zend/zend_execute.h2
-rw-r--r--Zend/zend_inheritance.c23
-rw-r--r--Zend/zend_opcode.c7
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);