mirror of
https://github.com/php/php-src.git
synced 2025-08-16 14:08:47 +02:00
Fixed support for extra arguments in conjunction with variadiv argument.
Use compile time flags to check if we call constructor and result of ZEND_NEW is used or not.
This commit is contained in:
parent
6a092734ed
commit
3f0ee308a0
7 changed files with 93 additions and 83 deletions
|
@ -409,7 +409,7 @@ ZEND_FUNCTION(func_num_args)
|
||||||
Get the $arg_num'th argument that was passed to the function */
|
Get the $arg_num'th argument that was passed to the function */
|
||||||
ZEND_FUNCTION(func_get_arg)
|
ZEND_FUNCTION(func_get_arg)
|
||||||
{
|
{
|
||||||
int arg_count;
|
int arg_count, first_extra_arg;
|
||||||
zval *arg;
|
zval *arg;
|
||||||
long requested_offset;
|
long requested_offset;
|
||||||
zend_execute_data *ex;
|
zend_execute_data *ex;
|
||||||
|
@ -436,8 +436,12 @@ ZEND_FUNCTION(func_get_arg)
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requested_offset >= ex->func->op_array.num_args && (ex->num_args > ex->func->op_array.num_args)) {
|
first_extra_arg = 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);
|
if (ex->func->op_array.fn_flags & ZEND_ACC_VARIADIC) {
|
||||||
|
first_extra_arg--;
|
||||||
|
}
|
||||||
|
if (requested_offset >= first_extra_arg && (ex->num_args > first_extra_arg)) {
|
||||||
|
arg = EX_VAR_NUM_2(ex, ex->func->op_array.last_var + ex->func->op_array.T) + (requested_offset - first_extra_arg);
|
||||||
} else {
|
} else {
|
||||||
arg = ZEND_CALL_ARG(ex, requested_offset + 1);
|
arg = ZEND_CALL_ARG(ex, requested_offset + 1);
|
||||||
}
|
}
|
||||||
|
@ -450,7 +454,7 @@ ZEND_FUNCTION(func_get_arg)
|
||||||
ZEND_FUNCTION(func_get_args)
|
ZEND_FUNCTION(func_get_args)
|
||||||
{
|
{
|
||||||
zval *p;
|
zval *p;
|
||||||
int arg_count;
|
int arg_count, first_extra_arg;
|
||||||
int i;
|
int i;
|
||||||
zend_execute_data *ex = EG(current_execute_data);
|
zend_execute_data *ex = EG(current_execute_data);
|
||||||
|
|
||||||
|
@ -465,12 +469,16 @@ ZEND_FUNCTION(func_get_args)
|
||||||
if (arg_count) {
|
if (arg_count) {
|
||||||
Bucket *q;
|
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);
|
zend_hash_real_init(Z_ARRVAL_P(return_value), 1);
|
||||||
i = 0;
|
i = 0;
|
||||||
q = Z_ARRVAL_P(return_value)->arData;
|
q = Z_ARRVAL_P(return_value)->arData;
|
||||||
p = ZEND_CALL_ARG(ex, 1);
|
p = ZEND_CALL_ARG(ex, 1);
|
||||||
if (ex->num_args > ex->func->op_array.num_args) {
|
if (ex->num_args > first_extra_arg) {
|
||||||
while (i < ex->func->op_array.num_args) {
|
while (i < first_extra_arg) {
|
||||||
q->h = i;
|
q->h = i;
|
||||||
q->key = NULL;
|
q->key = NULL;
|
||||||
if (!Z_ISREF_P(p)) {
|
if (!Z_ISREF_P(p)) {
|
||||||
|
@ -1985,14 +1993,21 @@ static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array TS
|
||||||
int i = 0;
|
int i = 0;
|
||||||
zval *p = ZEND_CALL_ARG(call, 1);
|
zval *p = ZEND_CALL_ARG(call, 1);
|
||||||
|
|
||||||
if (call->func->type == ZEND_USER_FUNCTION && (call->num_args > call->func->op_array.num_args)) {
|
if (call->func->type == ZEND_USER_FUNCTION) {
|
||||||
while (i < call->func->op_array.num_args) {
|
int first_extra_arg = 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);
|
if (call->func->op_array.fn_flags & ZEND_ACC_VARIADIC) {
|
||||||
p++;
|
first_extra_arg--;
|
||||||
i++;
|
}
|
||||||
|
if (call->num_args > first_extra_arg) {
|
||||||
|
while (i < first_extra_arg) {
|
||||||
|
if (Z_REFCOUNTED_P(p)) Z_ADDREF_P(p);
|
||||||
|
zend_hash_next_index_insert_new(Z_ARRVAL_P(arg_array), p);
|
||||||
|
p++;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
p = EX_VAR_NUM_2(call, call->func->op_array.last_var + call->func->op_array.T);
|
||||||
}
|
}
|
||||||
p = EX_VAR_NUM_2(call, call->func->op_array.last_var + call->func->op_array.T);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (i < num_args) {
|
while (i < num_args) {
|
||||||
|
|
|
@ -1461,6 +1461,11 @@ void zend_do_free(znode *op1 TSRMLS_DC) /* {{{ */
|
||||||
&& opline->result.var == op1->u.op.var) {
|
&& opline->result.var == op1->u.op.var) {
|
||||||
if (opline->opcode == ZEND_NEW) {
|
if (opline->opcode == ZEND_NEW) {
|
||||||
opline->result_type |= EXT_TYPE_UNUSED;
|
opline->result_type |= EXT_TYPE_UNUSED;
|
||||||
|
opline = &CG(active_op_array)->opcodes[CG(active_op_array)->last-1];
|
||||||
|
while (opline->opcode != ZEND_DO_FCALL || opline->op1.num != ZEND_CALL_CTOR) {
|
||||||
|
opline--;
|
||||||
|
}
|
||||||
|
opline->op1.num |= ZEND_CALL_CTOR_RESULT_UNUSED;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2544,13 +2549,20 @@ void zend_do_end_function_call(znode *function_name, znode *result, int is_metho
|
||||||
}
|
}
|
||||||
opline = &CG(active_op_array)->opcodes[Z_LVAL(function_name->u.constant)];
|
opline = &CG(active_op_array)->opcodes[Z_LVAL(function_name->u.constant)];
|
||||||
} else {
|
} else {
|
||||||
|
zend_uint call_flags = 0;
|
||||||
|
|
||||||
opline = &CG(active_op_array)->opcodes[fcall->op_number];
|
opline = &CG(active_op_array)->opcodes[fcall->op_number];
|
||||||
opline->extended_value = fcall->arg_num;
|
opline->extended_value = fcall->arg_num;
|
||||||
|
|
||||||
|
if (opline->opcode == ZEND_NEW) {
|
||||||
|
call_flags = ZEND_CALL_CTOR;
|
||||||
|
}
|
||||||
|
|
||||||
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
|
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
|
||||||
opline->opcode = ZEND_DO_FCALL;
|
opline->opcode = ZEND_DO_FCALL;
|
||||||
SET_UNUSED(opline->op1);
|
SET_UNUSED(opline->op1);
|
||||||
SET_UNUSED(opline->op2);
|
SET_UNUSED(opline->op2);
|
||||||
|
opline->op1.num = call_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
opline->result.var = get_temporary_variable(CG(active_op_array));
|
opline->result.var = get_temporary_variable(CG(active_op_array));
|
||||||
|
|
|
@ -379,7 +379,7 @@ struct _zend_execute_data {
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ZEND_CALL_CTOR (1 << 0)
|
#define ZEND_CALL_CTOR (1 << 0)
|
||||||
#define ZEND_CALL_CTOR_RESULT_USED (1 << 1)
|
#define ZEND_CALL_CTOR_RESULT_UNUSED (1 << 1)
|
||||||
#define ZEND_CALL_DONE (1 << 2)
|
#define ZEND_CALL_DONE (1 << 2)
|
||||||
|
|
||||||
#define ZEND_CALL_FRAME_SLOT \
|
#define ZEND_CALL_FRAME_SLOT \
|
||||||
|
@ -741,7 +741,6 @@ int zend_add_literal(zend_op_array *op_array, zval *zv TSRMLS_DC);
|
||||||
#define ZEND_PARSED_NEW (1<<6)
|
#define ZEND_PARSED_NEW (1<<6)
|
||||||
#define ZEND_PARSED_LIST_EXPR (1<<7)
|
#define ZEND_PARSED_LIST_EXPR (1<<7)
|
||||||
|
|
||||||
|
|
||||||
/* unset types */
|
/* unset types */
|
||||||
#define ZEND_UNSET_REG 0
|
#define ZEND_UNSET_REG 0
|
||||||
|
|
||||||
|
|
|
@ -1556,18 +1556,22 @@ static zend_always_inline void i_init_execute_data(zend_execute_data *execute_da
|
||||||
|
|
||||||
EG(opline_ptr) = &EX(opline);
|
EG(opline_ptr) = &EX(opline);
|
||||||
EX(opline) = UNEXPECTED((op_array->fn_flags & ZEND_ACC_INTERACTIVE) != 0) && EG(start_op) ? EG(start_op) : op_array->opcodes;
|
EX(opline) = UNEXPECTED((op_array->fn_flags & ZEND_ACC_INTERACTIVE) != 0) && EG(start_op) ? EG(start_op) : op_array->opcodes;
|
||||||
//??? EX(func) = (zend_function*)op_array;
|
|
||||||
EX(scope) = EG(scope);
|
EX(scope) = EG(scope);
|
||||||
EX(symbol_table) = EG(active_symbol_table);
|
EX(symbol_table) = EG(active_symbol_table);
|
||||||
|
|
||||||
if (UNEXPECTED(EX(symbol_table) != NULL)) {
|
if (UNEXPECTED(EX(symbol_table) != NULL)) {
|
||||||
zend_attach_symbol_table(execute_data);
|
zend_attach_symbol_table(execute_data);
|
||||||
} else {
|
} else {
|
||||||
|
zend_uint first_extra_arg = op_array->num_args;
|
||||||
if (UNEXPECTED(EX(num_args) > op_array->num_args)) {
|
|
||||||
|
if (UNEXPECTED((op_array->fn_flags & ZEND_ACC_VARIADIC) != 0)) {
|
||||||
|
first_extra_arg--;
|
||||||
|
}
|
||||||
|
if (UNEXPECTED(EX(num_args) > first_extra_arg)) {
|
||||||
/* move extra args into separate array after all CV and TMP vars */
|
/* 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);
|
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));
|
|
||||||
|
memmove(extra_args, EX_VAR_NUM(first_extra_arg), sizeof(zval) * (EX(num_args) - first_extra_arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
|
@ -211,7 +211,7 @@ static zend_always_inline void zend_vm_stack_extend(int count TSRMLS_DC)
|
||||||
EG(argument_stack) = p;
|
EG(argument_stack) = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame(zend_function *func, zend_uint num_args, zend_uchar flags, zend_class_entry *called_scope, zend_object *object, zend_execute_data *prev TSRMLS_DC)
|
||||||
{
|
{
|
||||||
int used_stack = ZEND_CALL_FRAME_SLOT + num_args;
|
int used_stack = ZEND_CALL_FRAME_SLOT + num_args;
|
||||||
zend_execute_data *call;
|
zend_execute_data *call;
|
||||||
|
@ -223,7 +223,7 @@ static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame(zend_
|
||||||
call = (zend_execute_data*)EG(argument_stack)->top;
|
call = (zend_execute_data*)EG(argument_stack)->top;
|
||||||
EG(argument_stack)->top += used_stack;
|
EG(argument_stack)->top += used_stack;
|
||||||
call->func = func;
|
call->func = func;
|
||||||
call->num_args = 0; //??? num_args;
|
call->num_args = 0;
|
||||||
call->flags = flags;
|
call->flags = flags;
|
||||||
call->called_scope = called_scope;
|
call->called_scope = called_scope;
|
||||||
call->object = object;
|
call->object = object;
|
||||||
|
@ -233,9 +233,11 @@ static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame(zend_
|
||||||
|
|
||||||
static zend_always_inline void zend_vm_stack_free_extra_args(zend_execute_data *call TSRMLS_DC)
|
static zend_always_inline void zend_vm_stack_free_extra_args(zend_execute_data *call TSRMLS_DC)
|
||||||
{
|
{
|
||||||
if (UNEXPECTED(call->num_args > call->func->op_array.num_args)) {
|
zend_uint first_extra_arg = call->func->op_array.num_args - ((call->func->common.fn_flags & ZEND_ACC_VARIADIC) != 0);
|
||||||
|
|
||||||
|
if (UNEXPECTED(call->num_args > first_extra_arg)) {
|
||||||
zval *end = EX_VAR_NUM_2(call, call->func->op_array.last_var + call->func->op_array.T);
|
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);
|
zval *p = end + (call->num_args - first_extra_arg);
|
||||||
do {
|
do {
|
||||||
p--;
|
p--;
|
||||||
i_zval_ptr_dtor_nogc(p ZEND_FILE_LINE_CC TSRMLS_CC);
|
i_zval_ptr_dtor_nogc(p ZEND_FILE_LINE_CC TSRMLS_CC);
|
||||||
|
|
|
@ -1773,7 +1773,6 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
|
||||||
{
|
{
|
||||||
vm_frame_kind frame_kind = EX(frame_kind);
|
vm_frame_kind frame_kind = EX(frame_kind);
|
||||||
zend_execute_data *prev_nested_call;
|
zend_execute_data *prev_nested_call;
|
||||||
zend_uint call_flags;
|
|
||||||
|
|
||||||
EG(current_execute_data) = EX(prev_execute_data);
|
EG(current_execute_data) = EX(prev_execute_data);
|
||||||
|
|
||||||
|
@ -1785,7 +1784,6 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
|
||||||
if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_CLOSURE) != 0) && EX(func)->op_array.prototype) {
|
if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_CLOSURE) != 0) && EX(func)->op_array.prototype) {
|
||||||
zval_ptr_dtor((zval*)EX(func)->op_array.prototype);
|
zval_ptr_dtor((zval*)EX(func)->op_array.prototype);
|
||||||
}
|
}
|
||||||
call_flags = EX(flags);
|
|
||||||
prev_nested_call = EX(prev_nested_call);
|
prev_nested_call = EX(prev_nested_call);
|
||||||
zend_vm_stack_free_extra_args(execute_data TSRMLS_CC);
|
zend_vm_stack_free_extra_args(execute_data TSRMLS_CC);
|
||||||
zend_vm_stack_free_call_frame(execute_data TSRMLS_CC);
|
zend_vm_stack_free_call_frame(execute_data TSRMLS_CC);
|
||||||
|
@ -1797,8 +1795,8 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
|
||||||
EG(active_symbol_table) = EX(symbol_table);
|
EG(active_symbol_table) = EX(symbol_table);
|
||||||
|
|
||||||
if (Z_OBJ(EG(This))) {
|
if (Z_OBJ(EG(This))) {
|
||||||
if (UNEXPECTED(EG(exception) != NULL) && (call_flags & ZEND_CALL_CTOR)) {
|
if (UNEXPECTED(EG(exception) != NULL) && (EX(opline)->op1.num & ZEND_CALL_CTOR)) {
|
||||||
if (call_flags & ZEND_CALL_CTOR_RESULT_USED) {
|
if (!(EX(opline)->op1.num & ZEND_CALL_CTOR_RESULT_UNUSED)) {
|
||||||
Z_DELREF(EG(This));
|
Z_DELREF(EG(This));
|
||||||
}
|
}
|
||||||
if (Z_REFCOUNT(EG(This)) == 1) {
|
if (Z_REFCOUNT(EG(This)) == 1) {
|
||||||
|
@ -2576,10 +2574,9 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
|
||||||
USE_OPLINE
|
USE_OPLINE
|
||||||
zend_execute_data *call = EX(call);
|
zend_execute_data *call = EX(call);
|
||||||
zend_function *fbc = call->func;
|
zend_function *fbc = call->func;
|
||||||
zend_uint call_flags = call->flags;
|
|
||||||
|
|
||||||
SAVE_OPLINE();
|
SAVE_OPLINE();
|
||||||
call->flags |= ZEND_CALL_DONE;
|
call->flags = ZEND_CALL_DONE;
|
||||||
if (UNEXPECTED((fbc->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) != 0)) {
|
if (UNEXPECTED((fbc->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) != 0)) {
|
||||||
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_ABSTRACT) != 0)) {
|
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_ABSTRACT) != 0)) {
|
||||||
zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", fbc->common.scope->name->val, fbc->common.function_name->val);
|
zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", fbc->common.scope->name->val, fbc->common.function_name->val);
|
||||||
|
@ -2753,8 +2750,8 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
|
||||||
|
|
||||||
ZEND_VM_C_LABEL(fcall_end_change_scope):
|
ZEND_VM_C_LABEL(fcall_end_change_scope):
|
||||||
if (Z_OBJ(EG(This))) {
|
if (Z_OBJ(EG(This))) {
|
||||||
if (UNEXPECTED(EG(exception) != NULL) && (call_flags & ZEND_CALL_CTOR)) {
|
if (UNEXPECTED(EG(exception) != NULL) && (opline->op1.num & ZEND_CALL_CTOR)) {
|
||||||
if (call_flags & ZEND_CALL_CTOR_RESULT_USED) {
|
if (!(opline->op1.num & ZEND_CALL_CTOR_RESULT_UNUSED)) {
|
||||||
Z_DELREF(EG(This));
|
Z_DELREF(EG(This));
|
||||||
}
|
}
|
||||||
if (Z_REFCOUNT(EG(This)) == 1) {
|
if (Z_REFCOUNT(EG(This)) == 1) {
|
||||||
|
@ -3343,31 +3340,23 @@ ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, ANY, ANY)
|
||||||
params = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
|
params = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
|
||||||
|
|
||||||
if (arg_num <= arg_count) {
|
if (arg_num <= arg_count) {
|
||||||
zval *param, tmp;
|
zval *param;
|
||||||
|
|
||||||
ZVAL_COPY_VALUE(&tmp, params);
|
|
||||||
array_init_size(params, arg_count - arg_num + 1);
|
array_init_size(params, arg_count - arg_num + 1);
|
||||||
param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T);
|
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)) {
|
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);
|
do {
|
||||||
zend_hash_next_index_insert_new(Z_ARRVAL_P(params), &tmp);
|
zend_verify_arg_type(EX(func), arg_num, param, opline->extended_value TSRMLS_CC);
|
||||||
if (param) {
|
zend_hash_next_index_insert_new(Z_ARRVAL_P(params), param);
|
||||||
while (++arg_num <= arg_count) {
|
if (Z_REFCOUNTED_P(param)) Z_ADDREF_P(param);
|
||||||
zend_verify_arg_type(EX(func), arg_num, param, opline->extended_value TSRMLS_CC);
|
param++;
|
||||||
zend_hash_next_index_insert_new(Z_ARRVAL_P(params), param);
|
} while (++arg_num <= arg_count);
|
||||||
if (Z_REFCOUNTED_P(param)) Z_ADDREF_P(param);
|
|
||||||
param++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
zend_hash_next_index_insert_new(Z_ARRVAL_P(params), &tmp);
|
do {
|
||||||
if (param) {
|
zend_hash_next_index_insert_new(Z_ARRVAL_P(params), param);
|
||||||
while (++arg_num <= arg_count) {
|
if (Z_REFCOUNTED_P(param)) Z_ADDREF_P(param);
|
||||||
zend_hash_next_index_insert_new(Z_ARRVAL_P(params), param);
|
param++;
|
||||||
if (Z_REFCOUNTED_P(param)) Z_ADDREF_P(param);
|
} while (++arg_num <= arg_count);
|
||||||
param++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
array_init(params);
|
array_init(params);
|
||||||
|
@ -3495,7 +3484,7 @@ ZEND_VM_HANDLER(68, ZEND_NEW, ANY, ANY)
|
||||||
EX(call) = zend_vm_stack_push_call_frame(
|
EX(call) = zend_vm_stack_push_call_frame(
|
||||||
constructor, opline->extended_value,
|
constructor, opline->extended_value,
|
||||||
RETURN_VALUE_USED(opline) ?
|
RETURN_VALUE_USED(opline) ?
|
||||||
(ZEND_CALL_CTOR | ZEND_CALL_CTOR_RESULT_USED) : ZEND_CALL_CTOR,
|
ZEND_CALL_CTOR : (ZEND_CALL_CTOR | ZEND_CALL_CTOR_RESULT_UNUSED),
|
||||||
Z_CE_P(EX_VAR(opline->op1.var)),
|
Z_CE_P(EX_VAR(opline->op1.var)),
|
||||||
Z_OBJ(object_zval),
|
Z_OBJ(object_zval),
|
||||||
EX(call) TSRMLS_CC);
|
EX(call) TSRMLS_CC);
|
||||||
|
@ -5177,7 +5166,7 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
|
||||||
|
|
||||||
if (call->object) {
|
if (call->object) {
|
||||||
if (call->flags & ZEND_CALL_CTOR) {
|
if (call->flags & ZEND_CALL_CTOR) {
|
||||||
if (call->flags & ZEND_CALL_CTOR_RESULT_USED) {
|
if (!(call->flags & ZEND_CALL_CTOR_RESULT_UNUSED)) {
|
||||||
GC_REFCOUNT(call->object)--;
|
GC_REFCOUNT(call->object)--;
|
||||||
}
|
}
|
||||||
if (GC_REFCOUNT(call->object) == 1) {
|
if (GC_REFCOUNT(call->object) == 1) {
|
||||||
|
|
|
@ -396,7 +396,6 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
|
||||||
{
|
{
|
||||||
vm_frame_kind frame_kind = EX(frame_kind);
|
vm_frame_kind frame_kind = EX(frame_kind);
|
||||||
zend_execute_data *prev_nested_call;
|
zend_execute_data *prev_nested_call;
|
||||||
zend_uint call_flags;
|
|
||||||
|
|
||||||
EG(current_execute_data) = EX(prev_execute_data);
|
EG(current_execute_data) = EX(prev_execute_data);
|
||||||
|
|
||||||
|
@ -408,7 +407,6 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
|
||||||
if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_CLOSURE) != 0) && EX(func)->op_array.prototype) {
|
if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_CLOSURE) != 0) && EX(func)->op_array.prototype) {
|
||||||
zval_ptr_dtor((zval*)EX(func)->op_array.prototype);
|
zval_ptr_dtor((zval*)EX(func)->op_array.prototype);
|
||||||
}
|
}
|
||||||
call_flags = EX(flags);
|
|
||||||
prev_nested_call = EX(prev_nested_call);
|
prev_nested_call = EX(prev_nested_call);
|
||||||
zend_vm_stack_free_extra_args(execute_data TSRMLS_CC);
|
zend_vm_stack_free_extra_args(execute_data TSRMLS_CC);
|
||||||
zend_vm_stack_free_call_frame(execute_data TSRMLS_CC);
|
zend_vm_stack_free_call_frame(execute_data TSRMLS_CC);
|
||||||
|
@ -420,8 +418,8 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
|
||||||
EG(active_symbol_table) = EX(symbol_table);
|
EG(active_symbol_table) = EX(symbol_table);
|
||||||
|
|
||||||
if (Z_OBJ(EG(This))) {
|
if (Z_OBJ(EG(This))) {
|
||||||
if (UNEXPECTED(EG(exception) != NULL) && (call_flags & ZEND_CALL_CTOR)) {
|
if (UNEXPECTED(EG(exception) != NULL) && (EX(opline)->op1.num & ZEND_CALL_CTOR)) {
|
||||||
if (call_flags & ZEND_CALL_CTOR_RESULT_USED) {
|
if (!(EX(opline)->op1.num & ZEND_CALL_CTOR_RESULT_UNUSED)) {
|
||||||
Z_DELREF(EG(This));
|
Z_DELREF(EG(This));
|
||||||
}
|
}
|
||||||
if (Z_REFCOUNT(EG(This)) == 1) {
|
if (Z_REFCOUNT(EG(This)) == 1) {
|
||||||
|
@ -528,10 +526,9 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||||
USE_OPLINE
|
USE_OPLINE
|
||||||
zend_execute_data *call = EX(call);
|
zend_execute_data *call = EX(call);
|
||||||
zend_function *fbc = call->func;
|
zend_function *fbc = call->func;
|
||||||
zend_uint call_flags = call->flags;
|
|
||||||
|
|
||||||
SAVE_OPLINE();
|
SAVE_OPLINE();
|
||||||
call->flags |= ZEND_CALL_DONE;
|
call->flags = ZEND_CALL_DONE;
|
||||||
if (UNEXPECTED((fbc->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) != 0)) {
|
if (UNEXPECTED((fbc->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) != 0)) {
|
||||||
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_ABSTRACT) != 0)) {
|
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_ABSTRACT) != 0)) {
|
||||||
zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", fbc->common.scope->name->val, fbc->common.function_name->val);
|
zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", fbc->common.scope->name->val, fbc->common.function_name->val);
|
||||||
|
@ -705,8 +702,8 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||||
|
|
||||||
fcall_end_change_scope:
|
fcall_end_change_scope:
|
||||||
if (Z_OBJ(EG(This))) {
|
if (Z_OBJ(EG(This))) {
|
||||||
if (UNEXPECTED(EG(exception) != NULL) && (call_flags & ZEND_CALL_CTOR)) {
|
if (UNEXPECTED(EG(exception) != NULL) && (opline->op1.num & ZEND_CALL_CTOR)) {
|
||||||
if (call_flags & ZEND_CALL_CTOR_RESULT_USED) {
|
if (!(opline->op1.num & ZEND_CALL_CTOR_RESULT_UNUSED)) {
|
||||||
Z_DELREF(EG(This));
|
Z_DELREF(EG(This));
|
||||||
}
|
}
|
||||||
if (Z_REFCOUNT(EG(This)) == 1) {
|
if (Z_REFCOUNT(EG(This)) == 1) {
|
||||||
|
@ -945,31 +942,23 @@ static int ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR
|
||||||
params = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
|
params = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
|
||||||
|
|
||||||
if (arg_num <= arg_count) {
|
if (arg_num <= arg_count) {
|
||||||
zval *param, tmp;
|
zval *param;
|
||||||
|
|
||||||
ZVAL_COPY_VALUE(&tmp, params);
|
|
||||||
array_init_size(params, arg_count - arg_num + 1);
|
array_init_size(params, arg_count - arg_num + 1);
|
||||||
param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T);
|
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)) {
|
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);
|
do {
|
||||||
zend_hash_next_index_insert_new(Z_ARRVAL_P(params), &tmp);
|
zend_verify_arg_type(EX(func), arg_num, param, opline->extended_value TSRMLS_CC);
|
||||||
if (param) {
|
zend_hash_next_index_insert_new(Z_ARRVAL_P(params), param);
|
||||||
while (++arg_num <= arg_count) {
|
if (Z_REFCOUNTED_P(param)) Z_ADDREF_P(param);
|
||||||
zend_verify_arg_type(EX(func), arg_num, param, opline->extended_value TSRMLS_CC);
|
param++;
|
||||||
zend_hash_next_index_insert_new(Z_ARRVAL_P(params), param);
|
} while (++arg_num <= arg_count);
|
||||||
if (Z_REFCOUNTED_P(param)) Z_ADDREF_P(param);
|
|
||||||
param++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
zend_hash_next_index_insert_new(Z_ARRVAL_P(params), &tmp);
|
do {
|
||||||
if (param) {
|
zend_hash_next_index_insert_new(Z_ARRVAL_P(params), param);
|
||||||
while (++arg_num <= arg_count) {
|
if (Z_REFCOUNTED_P(param)) Z_ADDREF_P(param);
|
||||||
zend_hash_next_index_insert_new(Z_ARRVAL_P(params), param);
|
param++;
|
||||||
if (Z_REFCOUNTED_P(param)) Z_ADDREF_P(param);
|
} while (++arg_num <= arg_count);
|
||||||
param++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
array_init(params);
|
array_init(params);
|
||||||
|
@ -1010,7 +999,7 @@ static int ZEND_FASTCALL ZEND_NEW_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||||
EX(call) = zend_vm_stack_push_call_frame(
|
EX(call) = zend_vm_stack_push_call_frame(
|
||||||
constructor, opline->extended_value,
|
constructor, opline->extended_value,
|
||||||
RETURN_VALUE_USED(opline) ?
|
RETURN_VALUE_USED(opline) ?
|
||||||
(ZEND_CALL_CTOR | ZEND_CALL_CTOR_RESULT_USED) : ZEND_CALL_CTOR,
|
ZEND_CALL_CTOR : (ZEND_CALL_CTOR | ZEND_CALL_CTOR_RESULT_UNUSED),
|
||||||
Z_CE_P(EX_VAR(opline->op1.var)),
|
Z_CE_P(EX_VAR(opline->op1.var)),
|
||||||
Z_OBJ(object_zval),
|
Z_OBJ(object_zval),
|
||||||
EX(call) TSRMLS_CC);
|
EX(call) TSRMLS_CC);
|
||||||
|
@ -1246,7 +1235,7 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
|
||||||
|
|
||||||
if (call->object) {
|
if (call->object) {
|
||||||
if (call->flags & ZEND_CALL_CTOR) {
|
if (call->flags & ZEND_CALL_CTOR) {
|
||||||
if (call->flags & ZEND_CALL_CTOR_RESULT_USED) {
|
if (!(call->flags & ZEND_CALL_CTOR_RESULT_UNUSED)) {
|
||||||
GC_REFCOUNT(call->object)--;
|
GC_REFCOUNT(call->object)--;
|
||||||
}
|
}
|
||||||
if (GC_REFCOUNT(call->object) == 1) {
|
if (GC_REFCOUNT(call->object) == 1) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue