#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
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) {
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--;
}
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;
#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()
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)
{
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;
zend_execute_data *call = EX(call);
zend_function *fbc = call->func;
zval *ret;
+ zval retval;
SAVE_OPLINE();
EX(call) = call->prev_execute_data;
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;
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_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)) {
}
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)) {
}
}
- 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;
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_call_frame(call);
if (!RETURN_VALUE_USED(opline)) {
- zval_ptr_dtor(EX_VAR(opline->result.var));
+ zval_ptr_dtor(ret);
}
}
}
} else if (EXPECTED(fbc->type < ZEND_USER_FUNCTION)) {
int should_change_scope = 0;
+ zval retval;
if (fbc->common.scope) {
should_change_scope = 1;
}
}
- 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;
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)) {
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)) {
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);
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;
}
}
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_execute_data *call = EX(call);
zend_function *fbc = call->func;
zval *ret;
+ zval retval;
SAVE_OPLINE();
EX(call) = call->prev_execute_data;
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;
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_call_frame(call);
if (!0) {
- zval_ptr_dtor(EX_VAR(opline->result.var));
+ zval_ptr_dtor(ret);
}
if (UNEXPECTED(EG(exception) != NULL)) {
zend_execute_data *call = EX(call);
zend_function *fbc = call->func;
zval *ret;
+ zval retval;
SAVE_OPLINE();
EX(call) = call->prev_execute_data;
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;
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_call_frame(call);
if (!1) {
- zval_ptr_dtor(EX_VAR(opline->result.var));
+ zval_ptr_dtor(ret);
}
if (UNEXPECTED(EG(exception) != NULL)) {
}
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)) {
}
}
- 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;
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_call_frame(call);
if (!0) {
- zval_ptr_dtor(EX_VAR(opline->result.var));
+ zval_ptr_dtor(ret);
}
}
}
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)) {
}
}
- 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;
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_call_frame(call);
if (!1) {
- zval_ptr_dtor(EX_VAR(opline->result.var));
+ zval_ptr_dtor(ret);
}
}
}
} else if (EXPECTED(fbc->type < ZEND_USER_FUNCTION)) {
int should_change_scope = 0;
+ zval retval;
if (fbc->common.scope) {
should_change_scope = 1;
}
}
- 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;
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)) {
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)) {
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);
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;
}
}
}
} else if (EXPECTED(fbc->type < ZEND_USER_FUNCTION)) {
int should_change_scope = 0;
+ zval retval;
if (fbc->common.scope) {
should_change_scope = 1;
}
}
- 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;
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)) {
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)) {
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);
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;
}
}
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;
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];
}
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");
}
/* 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);
}
}
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 {
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:
}
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 */
}
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);
}
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) {
}
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);
}
}
}
}
}
- } else { /* Au still needs to be assigned a T which is a bit dumb. Should consider changing Zend */
+ } else {
+ /* Code which gets here is using a wrongly built opcode such as RECV() */
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() */
- map_T[currT] = i;
- zend_bitset_incl(valid_T, currT);
- }
+ map_T[currT] = i;
+ zend_bitset_incl(valid_T, currT);
ZEND_RESULT(opline).var = NUM_VAR(i + offset);
}
}
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;
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()
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));
}
}
#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
#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 {