Skip to content

Commit

Permalink
Separate ISSET_ISEMPTY_CV/UNSET_CV from ISSET_ISEMPTY_VAR/UNSET_VAR
Browse files Browse the repository at this point in the history
  • Loading branch information
dstogov committed Jul 17, 2017
1 parent d9d3b2c commit 1180d8c
Show file tree
Hide file tree
Showing 14 changed files with 364 additions and 333 deletions.
7 changes: 3 additions & 4 deletions Zend/zend_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -2220,6 +2220,7 @@ ZEND_API int zend_is_smart_branch(zend_op *opline) /* {{{ */
case ZEND_IS_SMALLER:
case ZEND_IS_SMALLER_OR_EQUAL:
case ZEND_CASE:
case ZEND_ISSET_ISEMPTY_CV:
case ZEND_ISSET_ISEMPTY_VAR:
case ZEND_ISSET_ISEMPTY_DIM_OBJ:
case ZEND_ISSET_ISEMPTY_PROP_OBJ:
Expand Down Expand Up @@ -4290,8 +4291,7 @@ void zend_compile_unset(zend_ast *ast) /* {{{ */
if (is_this_fetch(var_ast)) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot unset $this");
} else if (zend_try_compile_cv(&var_node, var_ast) == SUCCESS) {
opline = zend_emit_op(NULL, ZEND_UNSET_VAR, &var_node, NULL);
opline->extended_value = ZEND_FETCH_LOCAL | ZEND_QUICK_SET;
opline = zend_emit_op(NULL, ZEND_UNSET_CV, &var_node, NULL);
} else {
opline = zend_compile_simple_var_no_cv(NULL, var_ast, BP_VAR_UNSET, 0);
opline->opcode = ZEND_UNSET_VAR;
Expand Down Expand Up @@ -7469,8 +7469,7 @@ void zend_compile_isset_or_empty(znode *result, zend_ast *ast) /* {{{ */
if (is_this_fetch(var_ast)) {
opline = zend_emit_op(result, ZEND_ISSET_ISEMPTY_THIS, NULL, NULL);
} else if (zend_try_compile_cv(&var_node, var_ast) == SUCCESS) {
opline = zend_emit_op(result, ZEND_ISSET_ISEMPTY_VAR, &var_node, NULL);
opline->extended_value = ZEND_FETCH_LOCAL | ZEND_QUICK_SET;
opline = zend_emit_op(result, ZEND_ISSET_ISEMPTY_CV, &var_node, NULL);
} else {
opline = zend_compile_simple_var_no_cv(result, var_ast, BP_VAR_IS, 0);
opline->opcode = ZEND_ISSET_ISEMPTY_VAR;
Expand Down
1 change: 0 additions & 1 deletion Zend/zend_compile.h
Original file line number Diff line number Diff line change
Expand Up @@ -906,7 +906,6 @@ void zend_assert_valid_class_name(const zend_string *const_name);
#define ZEND_ISSET 0x02000000
#define ZEND_ISEMPTY 0x01000000
#define ZEND_ISSET_ISEMPTY_MASK (ZEND_ISSET | ZEND_ISEMPTY)
#define ZEND_QUICK_SET 0x00800000

#define ZEND_FETCH_ARG_MASK 0x000fffff

Expand Down
135 changes: 71 additions & 64 deletions Zend/zend_vm_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -5327,32 +5327,36 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMPVAR|CV, ANY, EVAL)
ZEND_VM_CONTINUE();
}

ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH|ISSET)
ZEND_VM_HANDLER(196, ZEND_UNSET_CV, CV, UNUSED)
{
USE_OPLINE
zval tmp, *varname;
HashTable *target_symbol_table;
zend_free_op free_op1;
zval *var = EX_VAR(opline->op1.var);

SAVE_OPLINE();
if (OP1_TYPE == IS_CV &&
(opline->extended_value & ZEND_QUICK_SET)) {
zval *var = EX_VAR(opline->op1.var);

if (Z_REFCOUNTED_P(var)) {
zend_refcounted *garbage = Z_COUNTED_P(var);
if (Z_REFCOUNTED_P(var)) {
zend_refcounted *garbage = Z_COUNTED_P(var);

ZVAL_UNDEF(var);
if (!--GC_REFCOUNT(garbage)) {
zval_dtor_func(garbage);
} else {
gc_check_possible_root(garbage);
}
ZVAL_UNDEF(var);
if (!--GC_REFCOUNT(garbage)) {
SAVE_OPLINE();
zval_dtor_func(garbage);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
} else {
ZVAL_UNDEF(var);
gc_check_possible_root(garbage);
}
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
} else {
ZVAL_UNDEF(var);
}
ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
{
USE_OPLINE
zval tmp, *varname;
HashTable *target_symbol_table;
zend_free_op free_op1;

SAVE_OPLINE();

varname = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);

Expand Down Expand Up @@ -6131,63 +6135,66 @@ ZEND_VM_C_LABEL(fe_fetch_w_exit):
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}

ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH|ISSET)
ZEND_VM_HANDLER(197, ZEND_ISSET_ISEMPTY_CV, CV, UNUSED, ISSET)
{
USE_OPLINE
zval *value;
int result;

if (OP1_TYPE == IS_CV &&
(opline->extended_value & ZEND_QUICK_SET)) {
value = EX_VAR(opline->op1.var);
if (opline->extended_value & ZEND_ISSET) {
result =
Z_TYPE_P(value) > IS_NULL &&
(!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL);
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
SAVE_OPLINE();
result = !i_zend_is_true(value);
if (UNEXPECTED(EG(exception))) {
ZVAL_UNDEF(EX_VAR(opline->result.var));
HANDLE_EXCEPTION();
}
}
ZEND_VM_SMART_BRANCH(result, 0);
ZVAL_BOOL(EX_VAR(opline->result.var), result);
ZEND_VM_SET_NEXT_OPCODE(opline + 1);
ZEND_VM_CONTINUE();
} else {
zend_free_op free_op1;
zval tmp, *varname;
HashTable *target_symbol_table;

value = EX_VAR(opline->op1.var);
if (opline->extended_value & ZEND_ISSET) {
result =
Z_TYPE_P(value) > IS_NULL &&
(!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL);
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
SAVE_OPLINE();
varname = GET_OP1_ZVAL_PTR(BP_VAR_IS);
ZVAL_UNDEF(&tmp);
if (OP1_TYPE != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_STR(&tmp, zval_get_string(varname));
varname = &tmp;
result = !i_zend_is_true(value);
if (UNEXPECTED(EG(exception))) {
ZVAL_UNDEF(EX_VAR(opline->result.var));
HANDLE_EXCEPTION();
}
}
ZEND_VM_SMART_BRANCH(result, 0);
ZVAL_BOOL(EX_VAR(opline->result.var), result);
ZEND_VM_SET_NEXT_OPCODE(opline + 1);
ZEND_VM_CONTINUE();
}

target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK EXECUTE_DATA_CC);
value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname));
ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH|ISSET)
{
USE_OPLINE
zval *value;
int result;
zend_free_op free_op1;
zval tmp, *varname;
HashTable *target_symbol_table;

if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
zend_string_release(Z_STR(tmp));
}
FREE_OP1();
SAVE_OPLINE();
varname = GET_OP1_ZVAL_PTR(BP_VAR_IS);
ZVAL_UNDEF(&tmp);
if (OP1_TYPE != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_STR(&tmp, zval_get_string(varname));
varname = &tmp;
}

if (opline->extended_value & ZEND_ISSET) {
result = value && Z_TYPE_P(value) > IS_NULL &&
(!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL);
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
result = !value || !i_zend_is_true(value);
}
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK EXECUTE_DATA_CC);
value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname));

ZEND_VM_SMART_BRANCH(result, 1);
ZVAL_BOOL(EX_VAR(opline->result.var), result);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
zend_string_release(Z_STR(tmp));
}
FREE_OP1();

if (opline->extended_value & ZEND_ISSET) {
result = value && Z_TYPE_P(value) > IS_NULL &&
(!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL);
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
result = !value || !i_zend_is_true(value);
}

ZEND_VM_SMART_BRANCH(result, 1);
ZVAL_BOOL(EX_VAR(opline->result.var), result);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}

ZEND_VM_HANDLER(180, ZEND_ISSET_ISEMPTY_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR, ISSET)
Expand Down

0 comments on commit 1180d8c

Please sign in to comment.