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);
}
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;
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;
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) {
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) */
* +----------------------------------------+
* 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) |
+ * | ... |
* +----------------------------------------+
*/
} 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 {
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;
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);
}
}
zend_uint num_args = call->num_args;
if (num_args > 0) {
- zval *p;
- zval *end;
-
- 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;
+ zval *p = ZEND_CALL_ARG(call, num_args + 1);
+ zval *end = p - num_args;;
+
do {
p--;
i_zval_ptr_dtor_nogc(p ZEND_FILE_LINE_CC TSRMLS_CC);
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));
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);
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);