mirror of
https://github.com/php/php-src.git
synced 2024-11-24 10:24:11 +08:00
Move rare cases of DO_FCALL into separate helpers.
This commit is contained in:
parent
85f35a8fc1
commit
e95efb6312
@ -769,6 +769,23 @@ static int zend_verify_internal_arg_type(zend_function *zf, uint32_t arg_num, zv
|
||||
return 1;
|
||||
}
|
||||
|
||||
static zend_never_inline int zend_verify_internal_arg_types(zend_function *fbc, zend_execute_data *call)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t num_args = ZEND_CALL_NUM_ARGS(call);
|
||||
zval *p = ZEND_CALL_ARG(call, 1);
|
||||
|
||||
for (i = 0; i < num_args; ++i) {
|
||||
if (UNEXPECTED(!zend_verify_internal_arg_type(fbc, i + 1, p))) {
|
||||
EG(current_execute_data) = call->prev_execute_data;
|
||||
zend_vm_stack_free_args(call);
|
||||
return 0;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static zend_always_inline int zend_verify_arg_type(zend_function *zf, uint32_t arg_num, zval *arg, zval *default_value, void **cache_slot)
|
||||
{
|
||||
zend_arg_info *cur_arg_info;
|
||||
@ -2930,6 +2947,44 @@ already_compiled:
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_never_inline int zend_do_fcall_overloaded(zend_function *fbc, zend_execute_data *call, zval *ret) /* {{{ */
|
||||
{
|
||||
zend_object *object;
|
||||
|
||||
/* Not sure what should be done here if it's a static method */
|
||||
if (UNEXPECTED(Z_TYPE(call->This) != IS_OBJECT)) {
|
||||
zend_vm_stack_free_args(call);
|
||||
if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
|
||||
zend_string_release(fbc->common.function_name);
|
||||
}
|
||||
efree(fbc);
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
|
||||
zend_throw_error(NULL, "Cannot call overloaded function for non-object");
|
||||
return 0;
|
||||
}
|
||||
|
||||
object = Z_OBJ(call->This);
|
||||
EG(scope) = fbc->common.scope;
|
||||
|
||||
ZVAL_NULL(ret);
|
||||
Z_VAR_FLAGS_P(ret) = 0;
|
||||
|
||||
EG(current_execute_data) = call;
|
||||
object->handlers->call_method(fbc->common.function_name, object, call, ret);
|
||||
EG(current_execute_data) = call->prev_execute_data;
|
||||
|
||||
zend_vm_stack_free_args(call);
|
||||
|
||||
if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
|
||||
zend_string_release(fbc->common.function_name);
|
||||
}
|
||||
efree(fbc);
|
||||
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#ifdef HAVE_GCC_GLOBAL_REGS
|
||||
# if defined(__GNUC__) && ZEND_GCC_VERSION >= 4008 && defined(i386)
|
||||
# define ZEND_VM_FP_GLOBAL_REG "%esi"
|
||||
|
@ -3617,21 +3617,11 @@ ZEND_VM_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL))
|
||||
call->prev_execute_data = execute_data;
|
||||
EG(current_execute_data) = call;
|
||||
|
||||
if (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
|
||||
uint32_t i;
|
||||
uint32_t num_args = ZEND_CALL_NUM_ARGS(call);
|
||||
zval *p = ZEND_CALL_ARG(call, 1);
|
||||
|
||||
for (i = 0; i < num_args; ++i) {
|
||||
if (UNEXPECTED(!zend_verify_internal_arg_type(fbc, i + 1, p))) {
|
||||
EG(current_execute_data) = call->prev_execute_data;
|
||||
zend_vm_stack_free_args(call);
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
zend_throw_exception_internal(NULL);
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
p++;
|
||||
}
|
||||
if (UNEXPECTED(fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS)
|
||||
&& UNEXPECTED(!zend_verify_internal_arg_types(fbc, call))) {
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
zend_throw_exception_internal(NULL);
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
|
||||
ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval;
|
||||
@ -3739,25 +3729,15 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL))
|
||||
call->prev_execute_data = execute_data;
|
||||
EG(current_execute_data) = call;
|
||||
|
||||
if (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
|
||||
uint32_t i;
|
||||
uint32_t num_args = ZEND_CALL_NUM_ARGS(call);
|
||||
zval *p = ZEND_CALL_ARG(call, 1);
|
||||
|
||||
for (i = 0; i < num_args; ++i) {
|
||||
if (UNEXPECTED(!zend_verify_internal_arg_type(fbc, i + 1, p))) {
|
||||
EG(current_execute_data) = call->prev_execute_data;
|
||||
zend_vm_stack_free_args(call);
|
||||
if (RETURN_VALUE_USED(opline)) {
|
||||
ZVAL_UNDEF(EX_VAR(opline->result.var));
|
||||
}
|
||||
if (UNEXPECTED(should_change_scope)) {
|
||||
ZEND_VM_C_GOTO(fcall_end_change_scope);
|
||||
} else {
|
||||
ZEND_VM_C_GOTO(fcall_end);
|
||||
}
|
||||
}
|
||||
p++;
|
||||
if (UNEXPECTED(fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS)
|
||||
&& UNEXPECTED(!zend_verify_internal_arg_types(fbc, call))) {
|
||||
if (RETURN_VALUE_USED(opline)) {
|
||||
ZVAL_UNDEF(EX_VAR(opline->result.var));
|
||||
}
|
||||
if (UNEXPECTED(should_change_scope)) {
|
||||
ZEND_VM_C_GOTO(fcall_end_change_scope);
|
||||
} else {
|
||||
ZEND_VM_C_GOTO(fcall_end);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3793,41 +3773,17 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL))
|
||||
}
|
||||
} else { /* ZEND_OVERLOADED_FUNCTION */
|
||||
zval retval;
|
||||
/* Not sure what should be done here if it's a static method */
|
||||
if (UNEXPECTED(Z_TYPE(call->This) != IS_OBJECT)) {
|
||||
zend_vm_stack_free_args(call);
|
||||
if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
|
||||
zend_string_release(fbc->common.function_name);
|
||||
}
|
||||
efree(fbc);
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
|
||||
zend_throw_error(NULL, "Cannot call overloaded function for non-object");
|
||||
ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval;
|
||||
|
||||
call->prev_execute_data = execute_data;
|
||||
|
||||
if (UNEXPECTED(!zend_do_fcall_overloaded(fbc, call, ret))) {
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
|
||||
object = Z_OBJ(call->This);
|
||||
EG(scope) = fbc->common.scope;
|
||||
|
||||
ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval;
|
||||
ZVAL_NULL(ret);
|
||||
|
||||
call->prev_execute_data = execute_data;
|
||||
EG(current_execute_data) = call;
|
||||
object->handlers->call_method(fbc->common.function_name, object, call, ret);
|
||||
EG(current_execute_data) = call->prev_execute_data;
|
||||
|
||||
zend_vm_stack_free_args(call);
|
||||
|
||||
if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
|
||||
zend_string_release(fbc->common.function_name);
|
||||
}
|
||||
efree(fbc);
|
||||
|
||||
if (!RETURN_VALUE_USED(opline)) {
|
||||
zval_ptr_dtor(ret);
|
||||
} else {
|
||||
Z_VAR_FLAGS_P(ret) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -7922,25 +7878,13 @@ ZEND_VM_HANDLER(158, ZEND_CALL_TRAMPOLINE, ANY, ANY)
|
||||
|
||||
EG(current_execute_data) = call;
|
||||
|
||||
if (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
|
||||
uint32_t i;
|
||||
uint32_t num_args = ZEND_CALL_NUM_ARGS(call);
|
||||
zval *p = ZEND_CALL_ARG(call, 1);
|
||||
|
||||
EG(current_execute_data) = call;
|
||||
|
||||
for (i = 0; i < num_args; ++i) {
|
||||
if (UNEXPECTED(!zend_verify_internal_arg_type(fbc, i + 1, p))) {
|
||||
EG(current_execute_data) = call->prev_execute_data;
|
||||
zend_vm_stack_free_args(call);
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
if (ret) {
|
||||
ZVAL_UNDEF(ret);
|
||||
}
|
||||
ZEND_VM_C_GOTO(call_trampoline_end);
|
||||
}
|
||||
p++;
|
||||
if (UNEXPECTED(fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS)
|
||||
&& UNEXPECTED(!zend_verify_internal_arg_types(fbc, call))) {
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
if (ret) {
|
||||
ZVAL_UNDEF(ret);
|
||||
}
|
||||
ZEND_VM_C_GOTO(call_trampoline_end);
|
||||
}
|
||||
|
||||
if (ret == NULL) {
|
||||
|
@ -793,21 +793,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_U
|
||||
call->prev_execute_data = execute_data;
|
||||
EG(current_execute_data) = call;
|
||||
|
||||
if (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
|
||||
uint32_t i;
|
||||
uint32_t num_args = ZEND_CALL_NUM_ARGS(call);
|
||||
zval *p = ZEND_CALL_ARG(call, 1);
|
||||
|
||||
for (i = 0; i < num_args; ++i) {
|
||||
if (UNEXPECTED(!zend_verify_internal_arg_type(fbc, i + 1, p))) {
|
||||
EG(current_execute_data) = call->prev_execute_data;
|
||||
zend_vm_stack_free_args(call);
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
zend_throw_exception_internal(NULL);
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
p++;
|
||||
}
|
||||
if (UNEXPECTED(fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS)
|
||||
&& UNEXPECTED(!zend_verify_internal_arg_types(fbc, call))) {
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
zend_throw_exception_internal(NULL);
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
|
||||
ret = 0 ? EX_VAR(opline->result.var) : &retval;
|
||||
@ -897,21 +887,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_U
|
||||
call->prev_execute_data = execute_data;
|
||||
EG(current_execute_data) = call;
|
||||
|
||||
if (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
|
||||
uint32_t i;
|
||||
uint32_t num_args = ZEND_CALL_NUM_ARGS(call);
|
||||
zval *p = ZEND_CALL_ARG(call, 1);
|
||||
|
||||
for (i = 0; i < num_args; ++i) {
|
||||
if (UNEXPECTED(!zend_verify_internal_arg_type(fbc, i + 1, p))) {
|
||||
EG(current_execute_data) = call->prev_execute_data;
|
||||
zend_vm_stack_free_args(call);
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
zend_throw_exception_internal(NULL);
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
p++;
|
||||
}
|
||||
if (UNEXPECTED(fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS)
|
||||
&& UNEXPECTED(!zend_verify_internal_arg_types(fbc, call))) {
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
zend_throw_exception_internal(NULL);
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
|
||||
ret = 1 ? EX_VAR(opline->result.var) : &retval;
|
||||
@ -1019,25 +999,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HA
|
||||
call->prev_execute_data = execute_data;
|
||||
EG(current_execute_data) = call;
|
||||
|
||||
if (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
|
||||
uint32_t i;
|
||||
uint32_t num_args = ZEND_CALL_NUM_ARGS(call);
|
||||
zval *p = ZEND_CALL_ARG(call, 1);
|
||||
|
||||
for (i = 0; i < num_args; ++i) {
|
||||
if (UNEXPECTED(!zend_verify_internal_arg_type(fbc, i + 1, p))) {
|
||||
EG(current_execute_data) = call->prev_execute_data;
|
||||
zend_vm_stack_free_args(call);
|
||||
if (0) {
|
||||
ZVAL_UNDEF(EX_VAR(opline->result.var));
|
||||
}
|
||||
if (UNEXPECTED(should_change_scope)) {
|
||||
goto fcall_end_change_scope;
|
||||
} else {
|
||||
goto fcall_end;
|
||||
}
|
||||
}
|
||||
p++;
|
||||
if (UNEXPECTED(fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS)
|
||||
&& UNEXPECTED(!zend_verify_internal_arg_types(fbc, call))) {
|
||||
if (0) {
|
||||
ZVAL_UNDEF(EX_VAR(opline->result.var));
|
||||
}
|
||||
if (UNEXPECTED(should_change_scope)) {
|
||||
goto fcall_end_change_scope;
|
||||
} else {
|
||||
goto fcall_end;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1073,41 +1043,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HA
|
||||
}
|
||||
} else { /* ZEND_OVERLOADED_FUNCTION */
|
||||
zval retval;
|
||||
/* Not sure what should be done here if it's a static method */
|
||||
if (UNEXPECTED(Z_TYPE(call->This) != IS_OBJECT)) {
|
||||
zend_vm_stack_free_args(call);
|
||||
if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
|
||||
zend_string_release(fbc->common.function_name);
|
||||
}
|
||||
efree(fbc);
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
|
||||
zend_throw_error(NULL, "Cannot call overloaded function for non-object");
|
||||
ret = 0 ? EX_VAR(opline->result.var) : &retval;
|
||||
|
||||
call->prev_execute_data = execute_data;
|
||||
|
||||
if (UNEXPECTED(!zend_do_fcall_overloaded(fbc, call, ret))) {
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
|
||||
object = Z_OBJ(call->This);
|
||||
EG(scope) = fbc->common.scope;
|
||||
|
||||
ret = 0 ? EX_VAR(opline->result.var) : &retval;
|
||||
ZVAL_NULL(ret);
|
||||
|
||||
call->prev_execute_data = execute_data;
|
||||
EG(current_execute_data) = call;
|
||||
object->handlers->call_method(fbc->common.function_name, object, call, ret);
|
||||
EG(current_execute_data) = call->prev_execute_data;
|
||||
|
||||
zend_vm_stack_free_args(call);
|
||||
|
||||
if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
|
||||
zend_string_release(fbc->common.function_name);
|
||||
}
|
||||
efree(fbc);
|
||||
|
||||
if (!0) {
|
||||
zval_ptr_dtor(ret);
|
||||
} else {
|
||||
Z_VAR_FLAGS_P(ret) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1214,25 +1160,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_USED_HAND
|
||||
call->prev_execute_data = execute_data;
|
||||
EG(current_execute_data) = call;
|
||||
|
||||
if (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
|
||||
uint32_t i;
|
||||
uint32_t num_args = ZEND_CALL_NUM_ARGS(call);
|
||||
zval *p = ZEND_CALL_ARG(call, 1);
|
||||
|
||||
for (i = 0; i < num_args; ++i) {
|
||||
if (UNEXPECTED(!zend_verify_internal_arg_type(fbc, i + 1, p))) {
|
||||
EG(current_execute_data) = call->prev_execute_data;
|
||||
zend_vm_stack_free_args(call);
|
||||
if (1) {
|
||||
ZVAL_UNDEF(EX_VAR(opline->result.var));
|
||||
}
|
||||
if (UNEXPECTED(should_change_scope)) {
|
||||
goto fcall_end_change_scope;
|
||||
} else {
|
||||
goto fcall_end;
|
||||
}
|
||||
}
|
||||
p++;
|
||||
if (UNEXPECTED(fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS)
|
||||
&& UNEXPECTED(!zend_verify_internal_arg_types(fbc, call))) {
|
||||
if (1) {
|
||||
ZVAL_UNDEF(EX_VAR(opline->result.var));
|
||||
}
|
||||
if (UNEXPECTED(should_change_scope)) {
|
||||
goto fcall_end_change_scope;
|
||||
} else {
|
||||
goto fcall_end;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1268,41 +1204,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_USED_HAND
|
||||
}
|
||||
} else { /* ZEND_OVERLOADED_FUNCTION */
|
||||
zval retval;
|
||||
/* Not sure what should be done here if it's a static method */
|
||||
if (UNEXPECTED(Z_TYPE(call->This) != IS_OBJECT)) {
|
||||
zend_vm_stack_free_args(call);
|
||||
if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
|
||||
zend_string_release(fbc->common.function_name);
|
||||
}
|
||||
efree(fbc);
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
|
||||
zend_throw_error(NULL, "Cannot call overloaded function for non-object");
|
||||
ret = 1 ? EX_VAR(opline->result.var) : &retval;
|
||||
|
||||
call->prev_execute_data = execute_data;
|
||||
|
||||
if (UNEXPECTED(!zend_do_fcall_overloaded(fbc, call, ret))) {
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
|
||||
object = Z_OBJ(call->This);
|
||||
EG(scope) = fbc->common.scope;
|
||||
|
||||
ret = 1 ? EX_VAR(opline->result.var) : &retval;
|
||||
ZVAL_NULL(ret);
|
||||
|
||||
call->prev_execute_data = execute_data;
|
||||
EG(current_execute_data) = call;
|
||||
object->handlers->call_method(fbc->common.function_name, object, call, ret);
|
||||
EG(current_execute_data) = call->prev_execute_data;
|
||||
|
||||
zend_vm_stack_free_args(call);
|
||||
|
||||
if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
|
||||
zend_string_release(fbc->common.function_name);
|
||||
}
|
||||
efree(fbc);
|
||||
|
||||
if (!1) {
|
||||
zval_ptr_dtor(ret);
|
||||
} else {
|
||||
Z_VAR_FLAGS_P(ret) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2148,25 +2060,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(Z
|
||||
|
||||
EG(current_execute_data) = call;
|
||||
|
||||
if (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
|
||||
uint32_t i;
|
||||
uint32_t num_args = ZEND_CALL_NUM_ARGS(call);
|
||||
zval *p = ZEND_CALL_ARG(call, 1);
|
||||
|
||||
EG(current_execute_data) = call;
|
||||
|
||||
for (i = 0; i < num_args; ++i) {
|
||||
if (UNEXPECTED(!zend_verify_internal_arg_type(fbc, i + 1, p))) {
|
||||
EG(current_execute_data) = call->prev_execute_data;
|
||||
zend_vm_stack_free_args(call);
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
if (ret) {
|
||||
ZVAL_UNDEF(ret);
|
||||
}
|
||||
goto call_trampoline_end;
|
||||
}
|
||||
p++;
|
||||
if (UNEXPECTED(fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS)
|
||||
&& UNEXPECTED(!zend_verify_internal_arg_types(fbc, call))) {
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
if (ret) {
|
||||
ZVAL_UNDEF(ret);
|
||||
}
|
||||
goto call_trampoline_end;
|
||||
}
|
||||
|
||||
if (ret == NULL) {
|
||||
|
Loading…
Reference in New Issue
Block a user