mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Keep extra args in the same VM stack segment (after all CV and TMP vars)
This commit is contained in:
parent
04c87b9961
commit
032f33591a
7 changed files with 24 additions and 39 deletions
|
@ -436,8 +436,8 @@ ZEND_FUNCTION(func_get_arg)
|
|||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (ex->extra_args && requested_offset >= ex->func->op_array.num_args) {
|
||||
arg = ex->extra_args + (requested_offset - ex->func->op_array.num_args);
|
||||
if (requested_offset >= ex->func->op_array.num_args && (ex->num_args > ex->func->op_array.num_args)) {
|
||||
arg = EX_VAR_NUM_2(ex, ex->func->op_array.last_var + ex->func->op_array.T) + (requested_offset - ex->func->op_array.num_args);
|
||||
} else {
|
||||
arg = ZEND_CALL_ARG(ex, requested_offset + 1);
|
||||
}
|
||||
|
@ -469,7 +469,7 @@ ZEND_FUNCTION(func_get_args)
|
|||
i = 0;
|
||||
q = Z_ARRVAL_P(return_value)->arData;
|
||||
p = ZEND_CALL_ARG(ex, 1);
|
||||
if (ex->extra_args) {
|
||||
if (ex->num_args > ex->func->op_array.num_args) {
|
||||
while (i < ex->func->op_array.num_args) {
|
||||
q->h = i;
|
||||
q->key = NULL;
|
||||
|
@ -482,7 +482,7 @@ ZEND_FUNCTION(func_get_args)
|
|||
q++;
|
||||
i++;
|
||||
}
|
||||
p = ex->extra_args;
|
||||
p = EX_VAR_NUM_2(ex, ex->func->op_array.last_var + ex->func->op_array.T);
|
||||
}
|
||||
while (i < arg_count) {
|
||||
q->h = i;
|
||||
|
@ -1985,14 +1985,14 @@ static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array TS
|
|||
int i = 0;
|
||||
zval *p = ZEND_CALL_ARG(call, 1);
|
||||
|
||||
if (call->extra_args) {
|
||||
if (call->func->type == ZEND_USER_FUNCTION && (call->num_args > call->func->op_array.num_args)) {
|
||||
while (i < call->func->op_array.num_args) {
|
||||
if (Z_REFCOUNTED_P(p)) Z_ADDREF_P(p);
|
||||
zend_hash_next_index_insert_new(Z_ARRVAL_P(arg_array), p);
|
||||
p++;
|
||||
i++;
|
||||
}
|
||||
p = call->extra_args;
|
||||
p = EX_VAR_NUM_2(call, call->func->op_array.last_var + call->func->op_array.T);
|
||||
}
|
||||
|
||||
while (i < num_args) {
|
||||
|
|
|
@ -372,7 +372,6 @@ struct _zend_execute_data {
|
|||
void **run_time_cache;
|
||||
zend_execute_data *prev_execute_data;
|
||||
zval *return_value;
|
||||
zval *extra_args;
|
||||
vm_frame_kind frame_kind;
|
||||
zval old_error_reporting;
|
||||
struct _zend_op *fast_ret; /* used by FAST_CALL/FAST_RET (finally keyword) */
|
||||
|
|
|
@ -1531,10 +1531,14 @@ void zend_free_compiled_variables(zend_execute_data *execute_data TSRMLS_DC) /*
|
|||
* +----------------------------------------+
|
||||
* EX_CV_NUM(0) ---------> | VAR[0] = ARG[1] |
|
||||
* | ... |
|
||||
* | VAR[op_array->num_args-1] = ARG[N] |
|
||||
* | ... |
|
||||
* | VAR[op_array->last_var-1] |
|
||||
* | VAR[op_array->last_var] |
|
||||
* | VAR[op_array->last_var] = TMP[0] |
|
||||
* | ... |
|
||||
* | VAR[op_array->last_var+op_array->T-1] |
|
||||
* | ARG[N+1] (extra_args) |
|
||||
* | ... |
|
||||
* +----------------------------------------+
|
||||
*/
|
||||
|
||||
|
@ -1561,9 +1565,9 @@ static zend_always_inline void i_init_execute_data(zend_execute_data *execute_da
|
|||
} else {
|
||||
|
||||
if (UNEXPECTED(EX(num_args) > op_array->num_args)) {
|
||||
/* move extra args into separate array */
|
||||
EX(extra_args) = safe_emalloc(EX(num_args) - op_array->num_args, sizeof(zval), 0);
|
||||
memcpy(EX(extra_args), EX_VAR_NUM(op_array->num_args), sizeof(zval) * (EX(num_args) - op_array->num_args));
|
||||
/* move extra args into separate array after all CV and TMP vars */
|
||||
zval *extra_args = EX_VAR_NUM(op_array->last_var + op_array->T);
|
||||
memmove(extra_args, EX_VAR_NUM(op_array->num_args), sizeof(zval) * (EX(num_args) - op_array->num_args));
|
||||
}
|
||||
|
||||
do {
|
||||
|
|
|
@ -210,13 +210,11 @@ static zend_always_inline void zend_vm_stack_extend(int count TSRMLS_DC)
|
|||
|
||||
static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame(zend_function *func, zend_uint num_args, zend_uint flags, zend_class_entry *called_scope, zend_object *object, zend_execute_data *prev TSRMLS_DC)
|
||||
{
|
||||
int used_stack = ZEND_CALL_FRAME_SLOT;
|
||||
int used_stack = ZEND_CALL_FRAME_SLOT + num_args;
|
||||
zend_execute_data *call;
|
||||
|
||||
if (func && (func->type == ZEND_USER_FUNCTION || func->type == ZEND_EVAL_CODE)) {
|
||||
used_stack += MAX(func->op_array.last_var + func->op_array.T, num_args);
|
||||
} else {
|
||||
used_stack += num_args;
|
||||
if (func->type == ZEND_USER_FUNCTION || func->type == ZEND_EVAL_CODE) {
|
||||
used_stack += func->op_array.last_var + func->op_array.T - MIN(func->op_array.num_args, num_args);
|
||||
}
|
||||
ZEND_VM_STACK_GROW_IF_NEEDED(used_stack);
|
||||
call = (zend_execute_data*)EG(argument_stack)->top;
|
||||
|
@ -226,21 +224,19 @@ static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame(zend_
|
|||
call->called_scope = called_scope;
|
||||
call->object = object;
|
||||
call->prev_nested_call = prev;
|
||||
call->extra_args = NULL;
|
||||
EG(argument_stack)->top += used_stack;
|
||||
return call;
|
||||
}
|
||||
|
||||
static zend_always_inline void zend_vm_stack_free_extra_args(zend_execute_data *call TSRMLS_DC)
|
||||
{
|
||||
if (UNEXPECTED(call->extra_args != NULL)) {
|
||||
zval *p = call->extra_args + (call->num_args - call->func->op_array.num_args);
|
||||
zval *end = call->extra_args;
|
||||
if (UNEXPECTED(call->num_args > call->func->op_array.num_args)) {
|
||||
zval *end = EX_VAR_NUM_2(call, call->func->op_array.last_var + call->func->op_array.T);
|
||||
zval *p = end + (call->num_args - call->func->op_array.num_args);
|
||||
do {
|
||||
p--;
|
||||
i_zval_ptr_dtor_nogc(p ZEND_FILE_LINE_CC TSRMLS_CC);
|
||||
} while (p != end);
|
||||
efree(end);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -249,22 +245,9 @@ static zend_always_inline void zend_vm_stack_free_args(zend_execute_data *call T
|
|||
zend_uint num_args = call->num_args;
|
||||
|
||||
if (num_args > 0) {
|
||||
zval *p;
|
||||
zval *end;
|
||||
zval *p = ZEND_CALL_ARG(call, num_args + 1);
|
||||
zval *end = p - num_args;;
|
||||
|
||||
if (UNEXPECTED(call->extra_args != NULL)) {
|
||||
p = call->extra_args + (num_args - call->func->op_array.num_args);
|
||||
end = call->extra_args;
|
||||
do {
|
||||
p--;
|
||||
i_zval_ptr_dtor_nogc(p ZEND_FILE_LINE_CC TSRMLS_CC);
|
||||
} while (p != end);
|
||||
efree(end);
|
||||
num_args = call->func->op_array.num_args;
|
||||
}
|
||||
|
||||
p = ZEND_CALL_ARG(call, num_args + 1);
|
||||
end = p - num_args;
|
||||
do {
|
||||
p--;
|
||||
i_zval_ptr_dtor_nogc(p ZEND_FILE_LINE_CC TSRMLS_CC);
|
||||
|
|
|
@ -911,7 +911,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
|
|||
ZVAL_UNDEF(fci->retval);
|
||||
}
|
||||
}
|
||||
//??? zend_vm_stack_free_call_frame(EX(call), 0 TSRMLS_CC);
|
||||
|
||||
if (Z_OBJ(EG(This))) {
|
||||
zval_ptr_dtor(&EG(This));
|
||||
|
|
|
@ -3358,7 +3358,7 @@ ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, ANY, ANY)
|
|||
|
||||
ZVAL_COPY_VALUE(&tmp, params);
|
||||
array_init_size(params, arg_count - arg_num + 1);
|
||||
param = EX(extra_args);
|
||||
param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T);
|
||||
if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
|
||||
zend_verify_arg_type(EX(func), arg_num, &tmp, opline->extended_value TSRMLS_CC);
|
||||
zend_hash_next_index_insert_new(Z_ARRVAL_P(params), &tmp);
|
||||
|
|
|
@ -949,7 +949,7 @@ static int ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR
|
|||
|
||||
ZVAL_COPY_VALUE(&tmp, params);
|
||||
array_init_size(params, arg_count - arg_num + 1);
|
||||
param = EX(extra_args);
|
||||
param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T);
|
||||
if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
|
||||
zend_verify_arg_type(EX(func), arg_num, &tmp, opline->extended_value TSRMLS_CC);
|
||||
zend_hash_next_index_insert_new(Z_ARRVAL_P(params), &tmp);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue