mirror of
https://github.com/php/php-src.git
synced 2024-09-21 09:57:23 +00:00
Remove EXT_TYPE_UNUSED in favor of IS_UNUSED
This means we no longer allocate an unused VAR for the retval of instructions that support unused results. Nearly all instructions already used the result variable only if it was used. The only exception to this was the return value variable for internal function call results. I've adjusted the code to use a stack zval for the unused return case now. As we have retval specialization now, we know that it doesn't matter.
This commit is contained in:
parent
f75be35312
commit
5faedf5b3e
@ -61,7 +61,7 @@
|
||||
#define USED_RET() \
|
||||
(!EX(prev_execute_data) || \
|
||||
!ZEND_USER_CODE(EX(prev_execute_data)->func->common.type) || \
|
||||
!(EX(prev_execute_data)->opline->result_type & EXT_TYPE_UNUSED))
|
||||
(EX(prev_execute_data)->opline->result_type != IS_UNUSED))
|
||||
|
||||
#ifdef ZEND_ENABLE_STATIC_TSRMLS_CACHE
|
||||
#define ZEND_TSRMG TSRMG_STATIC
|
||||
|
@ -743,7 +743,7 @@ void zend_do_free(znode *op1) /* {{{ */
|
||||
their selves */
|
||||
zend_emit_op(NULL, ZEND_FREE, op1, NULL);
|
||||
} else {
|
||||
opline->result_type |= EXT_TYPE_UNUSED;
|
||||
opline->result_type = IS_UNUSED;
|
||||
}
|
||||
} else {
|
||||
while (opline >= CG(active_op_array)->opcodes) {
|
||||
@ -756,7 +756,7 @@ void zend_do_free(znode *op1) /* {{{ */
|
||||
if (opline->result_type==IS_VAR
|
||||
&& opline->result.var == op1->u.op.var) {
|
||||
if (opline->opcode == ZEND_NEW) {
|
||||
opline->result_type |= EXT_TYPE_UNUSED;
|
||||
opline->result_type = IS_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--;
|
||||
@ -2904,9 +2904,6 @@ void zend_compile_assign_ref(znode *result, zend_ast *ast) /* {{{ */
|
||||
}
|
||||
|
||||
opline = zend_emit_op(result, ZEND_ASSIGN_REF, &target_node, &source_node);
|
||||
if (!result) {
|
||||
opline->result_type |= EXT_TYPE_UNUSED;
|
||||
}
|
||||
|
||||
if (zend_is_call(source_ast)) {
|
||||
opline->extended_value = ZEND_RETURNS_FUNCTION;
|
||||
|
@ -683,8 +683,6 @@ struct _zend_execute_data {
|
||||
#define IS_UNUSED (1<<3) /* Unused variable */
|
||||
#define IS_CV (1<<4) /* Compiled variable */
|
||||
|
||||
#define EXT_TYPE_UNUSED (1<<5)
|
||||
|
||||
#include "zend_globals.h"
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
|
@ -68,7 +68,7 @@ static void zend_extension_statement_handler(const zend_extension *extension, ze
|
||||
static void zend_extension_fcall_begin_handler(const zend_extension *extension, zend_op_array *op_array);
|
||||
static void zend_extension_fcall_end_handler(const zend_extension *extension, zend_op_array *op_array);
|
||||
|
||||
#define RETURN_VALUE_USED(opline) (!((opline)->result_type & EXT_TYPE_UNUSED))
|
||||
#define RETURN_VALUE_USED(opline) ((opline)->result_type != IS_UNUSED)
|
||||
|
||||
static ZEND_FUNCTION(pass)
|
||||
{
|
||||
|
@ -680,8 +680,8 @@ ZEND_API int pass_two(zend_op_array *op_array)
|
||||
break;
|
||||
case ZEND_ASSERT_CHECK:
|
||||
/* If result of assert is unused, result of check is unused as well */
|
||||
if (op_array->opcodes[opline->op2.opline_num - 1].result_type & EXT_TYPE_UNUSED) {
|
||||
opline->result_type |= EXT_TYPE_UNUSED;
|
||||
if (op_array->opcodes[opline->op2.opline_num - 1].result_type == IS_UNUSED) {
|
||||
opline->result_type = IS_UNUSED;
|
||||
}
|
||||
ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op2);
|
||||
break;
|
||||
|
@ -3627,6 +3627,7 @@ ZEND_VM_HANDLER(129, ZEND_DO_ICALL, ANY, ANY, SPEC(RETVAL))
|
||||
zend_execute_data *call = EX(call);
|
||||
zend_function *fbc = call->func;
|
||||
zval *ret;
|
||||
zval retval;
|
||||
|
||||
SAVE_OPLINE();
|
||||
EX(call) = call->prev_execute_data;
|
||||
@ -3634,7 +3635,7 @@ ZEND_VM_HANDLER(129, ZEND_DO_ICALL, ANY, ANY, SPEC(RETVAL))
|
||||
call->prev_execute_data = execute_data;
|
||||
EG(current_execute_data) = call;
|
||||
|
||||
ret = EX_VAR(opline->result.var);
|
||||
ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval;
|
||||
ZVAL_NULL(ret);
|
||||
Z_VAR_FLAGS_P(ret) = 0;
|
||||
|
||||
@ -3644,7 +3645,7 @@ ZEND_VM_HANDLER(129, ZEND_DO_ICALL, ANY, ANY, SPEC(RETVAL))
|
||||
ZEND_ASSERT(
|
||||
EG(exception) || !call->func ||
|
||||
!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
|
||||
zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var)));
|
||||
zend_verify_internal_return_type(call->func, ret));
|
||||
#endif
|
||||
|
||||
EG(current_execute_data) = call->prev_execute_data;
|
||||
@ -3652,7 +3653,7 @@ ZEND_VM_HANDLER(129, ZEND_DO_ICALL, ANY, ANY, SPEC(RETVAL))
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
|
||||
if (!RETURN_VALUE_USED(opline)) {
|
||||
zval_ptr_dtor(EX_VAR(opline->result.var));
|
||||
zval_ptr_dtor(ret);
|
||||
}
|
||||
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
@ -3730,6 +3731,7 @@ ZEND_VM_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL))
|
||||
}
|
||||
EG(scope) = EX(func)->op_array.scope;
|
||||
} else {
|
||||
zval retval;
|
||||
ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
|
||||
|
||||
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
|
||||
@ -3762,7 +3764,7 @@ ZEND_VM_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL))
|
||||
}
|
||||
}
|
||||
|
||||
ret = EX_VAR(opline->result.var);
|
||||
ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval;
|
||||
ZVAL_NULL(ret);
|
||||
Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0;
|
||||
|
||||
@ -3772,7 +3774,7 @@ ZEND_VM_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL))
|
||||
ZEND_ASSERT(
|
||||
EG(exception) || !call->func ||
|
||||
!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
|
||||
zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var)));
|
||||
zend_verify_internal_return_type(call->func, ret));
|
||||
#endif
|
||||
|
||||
EG(current_execute_data) = call->prev_execute_data;
|
||||
@ -3780,7 +3782,7 @@ ZEND_VM_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL))
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
|
||||
if (!RETURN_VALUE_USED(opline)) {
|
||||
zval_ptr_dtor(EX_VAR(opline->result.var));
|
||||
zval_ptr_dtor(ret);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3857,6 +3859,7 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL))
|
||||
}
|
||||
} else if (EXPECTED(fbc->type < ZEND_USER_FUNCTION)) {
|
||||
int should_change_scope = 0;
|
||||
zval retval;
|
||||
|
||||
if (fbc->common.scope) {
|
||||
should_change_scope = 1;
|
||||
@ -3888,7 +3891,7 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL))
|
||||
}
|
||||
}
|
||||
|
||||
ret = EX_VAR(opline->result.var);
|
||||
ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval;
|
||||
ZVAL_NULL(ret);
|
||||
Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0;
|
||||
|
||||
@ -3903,14 +3906,14 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL))
|
||||
ZEND_ASSERT(
|
||||
EG(exception) || !call->func ||
|
||||
!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
|
||||
zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var)));
|
||||
zend_verify_internal_return_type(call->func, ret));
|
||||
#endif
|
||||
|
||||
EG(current_execute_data) = call->prev_execute_data;
|
||||
zend_vm_stack_free_args(call);
|
||||
|
||||
if (!RETURN_VALUE_USED(opline)) {
|
||||
zval_ptr_dtor(EX_VAR(opline->result.var));
|
||||
zval_ptr_dtor(ret);
|
||||
}
|
||||
|
||||
if (UNEXPECTED(should_change_scope)) {
|
||||
@ -3919,6 +3922,7 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL))
|
||||
ZEND_VM_C_GOTO(fcall_end);
|
||||
}
|
||||
} else { /* ZEND_OVERLOADED_FUNCTION */
|
||||
zval retval;
|
||||
/* Not sure what should be done here if it's a static method */
|
||||
object = Z_OBJ(call->This);
|
||||
if (UNEXPECTED(object == NULL)) {
|
||||
@ -3935,11 +3939,12 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL))
|
||||
|
||||
EG(scope) = fbc->common.scope;
|
||||
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
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, EX_VAR(opline->result.var));
|
||||
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);
|
||||
@ -3950,9 +3955,9 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL))
|
||||
efree(fbc);
|
||||
|
||||
if (!RETURN_VALUE_USED(opline)) {
|
||||
zval_ptr_dtor(EX_VAR(opline->result.var));
|
||||
zval_ptr_dtor(ret);
|
||||
} else {
|
||||
Z_VAR_FLAGS_P(EX_VAR(opline->result.var)) = 0;
|
||||
Z_VAR_FLAGS_P(ret) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -8106,7 +8111,7 @@ ZEND_VM_HANDLER(158, ZEND_CALL_TRAMPOLINE, ANY, ANY)
|
||||
ZEND_ASSERT(
|
||||
EG(exception) || !call->func ||
|
||||
!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
|
||||
zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var)));
|
||||
zend_verify_internal_return_type(call->func, ret));
|
||||
#endif
|
||||
|
||||
EG(current_execute_data) = call->prev_execute_data;
|
||||
|
@ -580,6 +580,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HA
|
||||
zend_execute_data *call = EX(call);
|
||||
zend_function *fbc = call->func;
|
||||
zval *ret;
|
||||
zval retval;
|
||||
|
||||
SAVE_OPLINE();
|
||||
EX(call) = call->prev_execute_data;
|
||||
@ -587,7 +588,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HA
|
||||
call->prev_execute_data = execute_data;
|
||||
EG(current_execute_data) = call;
|
||||
|
||||
ret = EX_VAR(opline->result.var);
|
||||
ret = 0 ? EX_VAR(opline->result.var) : &retval;
|
||||
ZVAL_NULL(ret);
|
||||
Z_VAR_FLAGS_P(ret) = 0;
|
||||
|
||||
@ -597,7 +598,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HA
|
||||
ZEND_ASSERT(
|
||||
EG(exception) || !call->func ||
|
||||
!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
|
||||
zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var)));
|
||||
zend_verify_internal_return_type(call->func, ret));
|
||||
#endif
|
||||
|
||||
EG(current_execute_data) = call->prev_execute_data;
|
||||
@ -605,7 +606,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HA
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
|
||||
if (!0) {
|
||||
zval_ptr_dtor(EX_VAR(opline->result.var));
|
||||
zval_ptr_dtor(ret);
|
||||
}
|
||||
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
@ -626,6 +627,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETVAL_USED_HAND
|
||||
zend_execute_data *call = EX(call);
|
||||
zend_function *fbc = call->func;
|
||||
zval *ret;
|
||||
zval retval;
|
||||
|
||||
SAVE_OPLINE();
|
||||
EX(call) = call->prev_execute_data;
|
||||
@ -633,7 +635,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETVAL_USED_HAND
|
||||
call->prev_execute_data = execute_data;
|
||||
EG(current_execute_data) = call;
|
||||
|
||||
ret = EX_VAR(opline->result.var);
|
||||
ret = 1 ? EX_VAR(opline->result.var) : &retval;
|
||||
ZVAL_NULL(ret);
|
||||
Z_VAR_FLAGS_P(ret) = 0;
|
||||
|
||||
@ -643,7 +645,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETVAL_USED_HAND
|
||||
ZEND_ASSERT(
|
||||
EG(exception) || !call->func ||
|
||||
!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
|
||||
zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var)));
|
||||
zend_verify_internal_return_type(call->func, ret));
|
||||
#endif
|
||||
|
||||
EG(current_execute_data) = call->prev_execute_data;
|
||||
@ -651,7 +653,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETVAL_USED_HAND
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
|
||||
if (!1) {
|
||||
zval_ptr_dtor(EX_VAR(opline->result.var));
|
||||
zval_ptr_dtor(ret);
|
||||
}
|
||||
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
@ -754,6 +756,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_U
|
||||
}
|
||||
EG(scope) = EX(func)->op_array.scope;
|
||||
} else {
|
||||
zval retval;
|
||||
ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
|
||||
|
||||
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
|
||||
@ -786,7 +789,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_U
|
||||
}
|
||||
}
|
||||
|
||||
ret = EX_VAR(opline->result.var);
|
||||
ret = 0 ? EX_VAR(opline->result.var) : &retval;
|
||||
ZVAL_NULL(ret);
|
||||
Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0;
|
||||
|
||||
@ -796,7 +799,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_U
|
||||
ZEND_ASSERT(
|
||||
EG(exception) || !call->func ||
|
||||
!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
|
||||
zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var)));
|
||||
zend_verify_internal_return_type(call->func, ret));
|
||||
#endif
|
||||
|
||||
EG(current_execute_data) = call->prev_execute_data;
|
||||
@ -804,7 +807,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_U
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
|
||||
if (!0) {
|
||||
zval_ptr_dtor(EX_VAR(opline->result.var));
|
||||
zval_ptr_dtor(ret);
|
||||
}
|
||||
}
|
||||
|
||||
@ -857,6 +860,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_U
|
||||
}
|
||||
EG(scope) = EX(func)->op_array.scope;
|
||||
} else {
|
||||
zval retval;
|
||||
ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
|
||||
|
||||
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
|
||||
@ -889,7 +893,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_U
|
||||
}
|
||||
}
|
||||
|
||||
ret = EX_VAR(opline->result.var);
|
||||
ret = 1 ? EX_VAR(opline->result.var) : &retval;
|
||||
ZVAL_NULL(ret);
|
||||
Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0;
|
||||
|
||||
@ -899,7 +903,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_U
|
||||
ZEND_ASSERT(
|
||||
EG(exception) || !call->func ||
|
||||
!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
|
||||
zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var)));
|
||||
zend_verify_internal_return_type(call->func, ret));
|
||||
#endif
|
||||
|
||||
EG(current_execute_data) = call->prev_execute_data;
|
||||
@ -907,7 +911,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_U
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
|
||||
if (!1) {
|
||||
zval_ptr_dtor(EX_VAR(opline->result.var));
|
||||
zval_ptr_dtor(ret);
|
||||
}
|
||||
}
|
||||
|
||||
@ -984,6 +988,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HA
|
||||
}
|
||||
} else if (EXPECTED(fbc->type < ZEND_USER_FUNCTION)) {
|
||||
int should_change_scope = 0;
|
||||
zval retval;
|
||||
|
||||
if (fbc->common.scope) {
|
||||
should_change_scope = 1;
|
||||
@ -1015,7 +1020,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HA
|
||||
}
|
||||
}
|
||||
|
||||
ret = EX_VAR(opline->result.var);
|
||||
ret = 0 ? EX_VAR(opline->result.var) : &retval;
|
||||
ZVAL_NULL(ret);
|
||||
Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0;
|
||||
|
||||
@ -1030,14 +1035,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HA
|
||||
ZEND_ASSERT(
|
||||
EG(exception) || !call->func ||
|
||||
!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
|
||||
zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var)));
|
||||
zend_verify_internal_return_type(call->func, ret));
|
||||
#endif
|
||||
|
||||
EG(current_execute_data) = call->prev_execute_data;
|
||||
zend_vm_stack_free_args(call);
|
||||
|
||||
if (!0) {
|
||||
zval_ptr_dtor(EX_VAR(opline->result.var));
|
||||
zval_ptr_dtor(ret);
|
||||
}
|
||||
|
||||
if (UNEXPECTED(should_change_scope)) {
|
||||
@ -1046,6 +1051,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HA
|
||||
goto fcall_end;
|
||||
}
|
||||
} else { /* ZEND_OVERLOADED_FUNCTION */
|
||||
zval retval;
|
||||
/* Not sure what should be done here if it's a static method */
|
||||
object = Z_OBJ(call->This);
|
||||
if (UNEXPECTED(object == NULL)) {
|
||||
@ -1062,11 +1068,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HA
|
||||
|
||||
EG(scope) = fbc->common.scope;
|
||||
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
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, EX_VAR(opline->result.var));
|
||||
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);
|
||||
@ -1077,9 +1084,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HA
|
||||
efree(fbc);
|
||||
|
||||
if (!0) {
|
||||
zval_ptr_dtor(EX_VAR(opline->result.var));
|
||||
zval_ptr_dtor(ret);
|
||||
} else {
|
||||
Z_VAR_FLAGS_P(EX_VAR(opline->result.var)) = 0;
|
||||
Z_VAR_FLAGS_P(ret) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1179,6 +1186,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_USED_HAND
|
||||
}
|
||||
} else if (EXPECTED(fbc->type < ZEND_USER_FUNCTION)) {
|
||||
int should_change_scope = 0;
|
||||
zval retval;
|
||||
|
||||
if (fbc->common.scope) {
|
||||
should_change_scope = 1;
|
||||
@ -1210,7 +1218,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_USED_HAND
|
||||
}
|
||||
}
|
||||
|
||||
ret = EX_VAR(opline->result.var);
|
||||
ret = 1 ? EX_VAR(opline->result.var) : &retval;
|
||||
ZVAL_NULL(ret);
|
||||
Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0;
|
||||
|
||||
@ -1225,14 +1233,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_USED_HAND
|
||||
ZEND_ASSERT(
|
||||
EG(exception) || !call->func ||
|
||||
!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
|
||||
zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var)));
|
||||
zend_verify_internal_return_type(call->func, ret));
|
||||
#endif
|
||||
|
||||
EG(current_execute_data) = call->prev_execute_data;
|
||||
zend_vm_stack_free_args(call);
|
||||
|
||||
if (!1) {
|
||||
zval_ptr_dtor(EX_VAR(opline->result.var));
|
||||
zval_ptr_dtor(ret);
|
||||
}
|
||||
|
||||
if (UNEXPECTED(should_change_scope)) {
|
||||
@ -1241,6 +1249,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_USED_HAND
|
||||
goto fcall_end;
|
||||
}
|
||||
} else { /* ZEND_OVERLOADED_FUNCTION */
|
||||
zval retval;
|
||||
/* Not sure what should be done here if it's a static method */
|
||||
object = Z_OBJ(call->This);
|
||||
if (UNEXPECTED(object == NULL)) {
|
||||
@ -1257,11 +1266,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_USED_HAND
|
||||
|
||||
EG(scope) = fbc->common.scope;
|
||||
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
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, EX_VAR(opline->result.var));
|
||||
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);
|
||||
@ -1272,9 +1282,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_USED_HAND
|
||||
efree(fbc);
|
||||
|
||||
if (!1) {
|
||||
zval_ptr_dtor(EX_VAR(opline->result.var));
|
||||
zval_ptr_dtor(ret);
|
||||
} else {
|
||||
Z_VAR_FLAGS_P(EX_VAR(opline->result.var)) = 0;
|
||||
Z_VAR_FLAGS_P(ret) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2153,7 +2163,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(Z
|
||||
ZEND_ASSERT(
|
||||
EG(exception) || !call->func ||
|
||||
!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
|
||||
zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var)));
|
||||
zend_verify_internal_return_type(call->func, ret));
|
||||
#endif
|
||||
|
||||
EG(current_execute_data) = call->prev_execute_data;
|
||||
@ -57293,7 +57303,7 @@ static const void *zend_vm_get_opcode_handler(zend_uchar opcode, const zend_op*
|
||||
if (spec & SPEC_RULE_OP1) offset = offset * 5 + zend_vm_decode[op->op1_type];
|
||||
if (spec & SPEC_RULE_OP2) offset = offset * 5 + zend_vm_decode[op->op2_type];
|
||||
if (spec & SPEC_RULE_OP_DATA) offset = offset * 5 + zend_vm_decode[(op + 1)->op1_type];
|
||||
if (spec & SPEC_RULE_RETVAL) offset = offset * 2 + ((op->result_type & EXT_TYPE_UNUSED) == 0);
|
||||
if (spec & SPEC_RULE_RETVAL) offset = offset * 2 + (op->result_type != IS_UNUSED);
|
||||
if (spec & SPEC_RULE_QUICK_ARG) offset = offset * 2 + (op->op2.num < MAX_ARG_FLAG_NUM);
|
||||
return zend_opcode_handlers[(spec & SPEC_START_MASK) + offset];
|
||||
}
|
||||
|
@ -2031,7 +2031,7 @@ function gen_vm($def, $skel) {
|
||||
out($f, "\tif (spec & SPEC_RULE_OP1) offset = offset * 5 + zend_vm_decode[op->op1_type];\n");
|
||||
out($f, "\tif (spec & SPEC_RULE_OP2) offset = offset * 5 + zend_vm_decode[op->op2_type];\n");
|
||||
out($f, "\tif (spec & SPEC_RULE_OP_DATA) offset = offset * 5 + zend_vm_decode[(op + 1)->op1_type];\n");
|
||||
out($f, "\tif (spec & SPEC_RULE_RETVAL) offset = offset * 2 + ((op->result_type & EXT_TYPE_UNUSED) == 0);\n");
|
||||
out($f, "\tif (spec & SPEC_RULE_RETVAL) offset = offset * 2 + (op->result_type != IS_UNUSED);\n");
|
||||
out($f, "\tif (spec & SPEC_RULE_QUICK_ARG) offset = offset * 2 + (op->op2.num < MAX_ARG_FLAG_NUM);\n");
|
||||
out($f, "\treturn zend_opcode_handlers[(spec & SPEC_START_MASK) + offset];\n");
|
||||
}
|
||||
|
@ -257,7 +257,7 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
|
||||
/* mark as removed (empty live range) */
|
||||
op_array->live_range[opline->op2.num].var = (uint32_t)-1;
|
||||
}
|
||||
ZEND_RESULT_TYPE(src) |= EXT_TYPE_UNUSED;
|
||||
ZEND_RESULT_TYPE(src) = IS_UNUSED;
|
||||
MAKE_NOP(opline);
|
||||
}
|
||||
}
|
||||
@ -1612,7 +1612,7 @@ static void zend_t_usage(zend_cfg *cfg, zend_op_array *op_array, zend_bitset use
|
||||
case ZEND_DO_ICALL:
|
||||
case ZEND_DO_UCALL:
|
||||
case ZEND_DO_FCALL_BY_NAME:
|
||||
opline->result_type |= EXT_TYPE_UNUSED;
|
||||
opline->result_type = IS_UNUSED;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@ -1624,7 +1624,7 @@ static void zend_t_usage(zend_cfg *cfg, zend_op_array *op_array, zend_bitset use
|
||||
case ZEND_POST_INC:
|
||||
case ZEND_POST_DEC:
|
||||
opline->opcode -= 2;
|
||||
opline->result_type = IS_VAR | EXT_TYPE_UNUSED;
|
||||
opline->result_type = IS_UNUSED;
|
||||
break;
|
||||
case ZEND_QM_ASSIGN:
|
||||
case ZEND_BOOL:
|
||||
|
@ -56,7 +56,7 @@ int zend_dfa_analyze_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx,
|
||||
}
|
||||
|
||||
if (ctx->debug_level & ZEND_DUMP_DFA_CFG) {
|
||||
zend_dump_op_array(op_array, ZEND_DUMP_CFG | ZEND_DUMP_HIDE_UNUSED_VARS, "dfa cfg", &ssa->cfg);
|
||||
zend_dump_op_array(op_array, ZEND_DUMP_CFG, "dfa cfg", &ssa->cfg);
|
||||
}
|
||||
|
||||
/* Compute Dominators Tree */
|
||||
@ -85,7 +85,7 @@ int zend_dfa_analyze_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx,
|
||||
}
|
||||
|
||||
if (ctx->debug_level & ZEND_DUMP_DFA_SSA) {
|
||||
zend_dump_op_array(op_array, ZEND_DUMP_SSA | ZEND_DUMP_HIDE_UNUSED_VARS, "before dfa pass", ssa);
|
||||
zend_dump_op_array(op_array, ZEND_DUMP_SSA, "before dfa pass", ssa);
|
||||
}
|
||||
|
||||
|
||||
@ -115,7 +115,7 @@ int zend_dfa_analyze_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx,
|
||||
void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx, zend_ssa *ssa)
|
||||
{
|
||||
if (ctx->debug_level & ZEND_DUMP_BEFORE_DFA_PASS) {
|
||||
zend_dump_op_array(op_array, ZEND_DUMP_SSA | ZEND_DUMP_HIDE_UNUSED_VARS, "before dfa pass", ssa);
|
||||
zend_dump_op_array(op_array, ZEND_DUMP_SSA, "before dfa pass", ssa);
|
||||
}
|
||||
|
||||
if (ssa->var_info) {
|
||||
@ -217,7 +217,7 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx
|
||||
}
|
||||
|
||||
if (ctx->debug_level & ZEND_DUMP_AFTER_DFA_PASS) {
|
||||
zend_dump_op_array(op_array, ZEND_DUMP_SSA | ZEND_DUMP_HIDE_UNUSED_VARS, "after dfa pass", ssa);
|
||||
zend_dump_op_array(op_array, ZEND_DUMP_SSA, "after dfa pass", ssa);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,16 +170,11 @@ void zend_optimize_temporary_variables(zend_op_array *op_array, zend_optimizer_c
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { /* Au still needs to be assigned a T which is a bit dumb. Should consider changing Zend */
|
||||
GET_AVAILABLE_T();
|
||||
|
||||
if (RESULT_UNUSED(opline)) {
|
||||
zend_bitset_excl(taken_T, i);
|
||||
} else {
|
||||
/* Code which gets here is using a wrongly built opcode such as RECV() */
|
||||
GET_AVAILABLE_T();
|
||||
map_T[currT] = i;
|
||||
zend_bitset_incl(valid_T, currT);
|
||||
}
|
||||
ZEND_RESULT(opline).var = NUM_VAR(i + offset);
|
||||
}
|
||||
}
|
||||
|
@ -418,7 +418,7 @@ continue_jmpznz_optimization:
|
||||
ZEND_OP1(next_op).var == ZEND_RESULT(opline).var) {
|
||||
MAKE_NOP(next_op);
|
||||
opline->opcode -= 2;
|
||||
ZEND_RESULT_TYPE(opline) = IS_VAR | EXT_TYPE_UNUSED;
|
||||
ZEND_RESULT_TYPE(opline) = IS_UNUSED;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -108,7 +108,7 @@ typedef struct _zend_cfg {
|
||||
CRT_CONSTANT_EX(op_array, node, (build_flags & ZEND_RT_CONSTANTS))
|
||||
|
||||
#define RETURN_VALUE_USED(opline) \
|
||||
(!((opline)->result_type & EXT_TYPE_UNUSED))
|
||||
((opline)->result_type != IS_UNUSED)
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
|
||||
|
@ -404,10 +404,6 @@ static void zend_dump_op(const zend_op_array *op_array, const zend_basic_block *
|
||||
zend_dump_var(op_array, opline->result_type, EX_VAR_TO_NUM(opline->result.var));
|
||||
}
|
||||
fprintf(stderr, " = ");
|
||||
} else if (!(dump_flags & ZEND_DUMP_HIDE_UNUSED_VARS) &&
|
||||
(opline->result_type & IS_VAR) &&
|
||||
(opline->result_type & EXT_TYPE_UNUSED)) {
|
||||
fprintf(stderr, "U%u = ", EX_VAR_TO_NUM(opline->result.var));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include "zend_dfg.h"
|
||||
|
||||
#define ZEND_DUMP_HIDE_UNREACHABLE (1<<0)
|
||||
#define ZEND_DUMP_HIDE_UNUSED_VARS (1<<1)
|
||||
/* Unused flag (1<<1) */
|
||||
#define ZEND_DUMP_CFG (1<<2)
|
||||
#define ZEND_DUMP_SSA (1<<3)
|
||||
#define ZEND_DUMP_RT_CONSTANTS ZEND_RT_CONSTANTS
|
||||
|
@ -43,7 +43,7 @@
|
||||
#define INV_COND_EX(op) ((op) == ZEND_JMPZ ? ZEND_JMPNZ_EX : ZEND_JMPZ_EX)
|
||||
#define INV_EX_COND_EX(op) ((op) == ZEND_JMPZ_EX ? ZEND_JMPNZ_EX : ZEND_JMPZ_EX)
|
||||
|
||||
#define RESULT_UNUSED(op) ((op->result_type & EXT_TYPE_UNUSED) != 0)
|
||||
#define RESULT_UNUSED(op) (op->result_type == IS_UNUSED)
|
||||
#define SAME_VAR(op1, op2) (op1 ## _type == op2 ## _type && op1.var == op2.var)
|
||||
|
||||
typedef struct _zend_optimizer_ctx {
|
||||
|
Loading…
Reference in New Issue
Block a user