Improved specialisation $this variable accessed through IS_UNUSED operand must be IS_OBJECT, so we don't have to check for its type or perform dereference.

This commit is contained in:
Dmitry Stogov 2014-10-10 16:36:12 +04:00
parent 3efc331701
commit af3354dc43
3 changed files with 1176 additions and 1157 deletions

View File

@ -701,49 +701,50 @@ static void zend_verify_missing_arg(zend_execute_data *execute_data, uint32_t ar
}
}
static inline void zend_assign_to_object(zval *retval, zval *object_ptr, zval *property_name, int value_type, const znode_op *value_op, const zend_execute_data *execute_data, int opcode, void **cache_slot TSRMLS_DC)
static zend_always_inline void zend_assign_to_object(zval *retval, zval *object, uint32_t object_op_type, zval *property_name, int value_type, const znode_op *value_op, const zend_execute_data *execute_data, int opcode, void **cache_slot TSRMLS_DC)
{
zend_free_op free_value;
zval *value = get_zval_ptr(value_type, value_op, execute_data, &free_value, BP_VAR_R);
zval tmp;
zval *object = object_ptr;
ZVAL_DEREF(object);
if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
if (UNEXPECTED(object == &EG(error_zval))) {
if (retval) {
ZVAL_NULL(retval);
if (object_op_type != IS_UNUSED) {
ZVAL_DEREF(object);
if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
if (UNEXPECTED(object == &EG(error_zval))) {
if (retval) {
ZVAL_NULL(retval);
}
FREE_OP(free_value);
return;
}
FREE_OP(free_value);
return;
}
if (EXPECTED(Z_TYPE_P(object) == IS_NULL ||
Z_TYPE_P(object) == IS_FALSE ||
(Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) {
zend_object *obj;
if (EXPECTED(Z_TYPE_P(object) == IS_NULL ||
Z_TYPE_P(object) == IS_FALSE ||
(Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) {
zend_object *obj;
zval_ptr_dtor(object);
object_init(object);
Z_ADDREF_P(object);
obj = Z_OBJ_P(object);
zend_error(E_WARNING, "Creating default object from empty value");
if (GC_REFCOUNT(obj) == 1) {
/* the enclosing container was deleted, obj is unreferenced */
zval_ptr_dtor(object);
object_init(object);
Z_ADDREF_P(object);
obj = Z_OBJ_P(object);
zend_error(E_WARNING, "Creating default object from empty value");
if (GC_REFCOUNT(obj) == 1) {
/* the enclosing container was deleted, obj is unreferenced */
if (retval) {
ZVAL_NULL(retval);
}
FREE_OP(free_value);
OBJ_RELEASE(obj);
return;
}
Z_DELREF_P(object);
} else {
zend_error(E_WARNING, "Attempt to assign property of non-object");
if (retval) {
ZVAL_NULL(retval);
}
FREE_OP(free_value);
OBJ_RELEASE(obj);
return;
}
Z_DELREF_P(object);
} else {
zend_error(E_WARNING, "Attempt to assign property of non-object");
if (retval) {
ZVAL_NULL(retval);
}
FREE_OP(free_value);
return;
}
}
@ -1301,31 +1302,30 @@ ZEND_API void zend_fetch_dimension_by_zval(zval *result, zval *container, zval *
zend_fetch_dimension_address_read_R(result, container, dim, IS_TMP_VAR TSRMLS_CC);
}
static void zend_fetch_property_address(zval *result, zval *container_ptr, zval *prop_ptr, void **cache_slot, int type, int is_ref TSRMLS_DC)
static zend_always_inline void zend_fetch_property_address(zval *result, zval *container, uint32_t container_op_type, zval *prop_ptr, void **cache_slot, int type, int is_ref TSRMLS_DC)
{
zval *container = container_ptr;
if (container_op_type != IS_UNUSED) {
ZVAL_DEREF(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
if (UNEXPECTED(container == &EG(error_zval))) {
ZVAL_INDIRECT(result, &EG(error_zval));
return;
}
ZVAL_DEREF(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
if (UNEXPECTED(container == &EG(error_zval))) {
ZVAL_INDIRECT(result, &EG(error_zval));
return;
}
/* this should modify object only if it's empty */
if (type != BP_VAR_UNSET &&
EXPECTED((Z_TYPE_P(container) == IS_NULL ||
Z_TYPE_P(container) == IS_FALSE ||
(Z_TYPE_P(container) == IS_STRING && Z_STRLEN_P(container)==0)))) {
zval_ptr_dtor_nogc(container);
object_init(container);
} else {
zend_error(E_WARNING, "Attempt to modify property of non-object");
ZVAL_INDIRECT(result, &EG(error_zval));
return;
/* this should modify object only if it's empty */
if (type != BP_VAR_UNSET &&
EXPECTED((Z_TYPE_P(container) == IS_NULL ||
Z_TYPE_P(container) == IS_FALSE ||
(Z_TYPE_P(container) == IS_STRING && Z_STRLEN_P(container)==0)))) {
zval_ptr_dtor_nogc(container);
object_init(container);
} else {
zend_error(E_WARNING, "Attempt to modify property of non-object");
ZVAL_INDIRECT(result, &EG(error_zval));
return;
}
}
}
if (EXPECTED(Z_OBJ_HT_P(container)->get_property_ptr_ptr)) {
zval *ptr = Z_OBJ_HT_P(container)->get_property_ptr_ptr(container, prop_ptr, type, cache_slot TSRMLS_CC);
if (NULL == ptr) {

View File

@ -339,11 +339,13 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
object = make_real_object(object TSRMLS_CC);
if (OP1_TYPE != IS_UNUSED) {
object = make_real_object(object TSRMLS_CC);
}
value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
zend_error(E_WARNING, "Attempt to assign property of non-object");
FREE_OP2();
FREE_OP(free_op_data1);
@ -433,7 +435,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_dim_helper, VAR|UNUSED|CV, CONST|TMP|VAR
container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW);
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
} else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
} else if (OP1_TYPE == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (OP1_TYPE == IS_VAR && !OP1_FREE) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@ -697,9 +699,11 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR|
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
object = make_real_object(object TSRMLS_CC); /* this should modify object only if it's empty */
if (OP1_TYPE != IS_UNUSED) {
object = make_real_object(object TSRMLS_CC); /* this should modify object only if it's empty */
}
if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
FREE_OP2();
if (RETURN_VALUE_USED(opline)) {
@ -789,9 +793,11 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
object = make_real_object(object TSRMLS_CC); /* this should modify object only if it's empty */
if (OP1_TYPE != IS_UNUSED) {
object = make_real_object(object TSRMLS_CC); /* this should modify object only if it's empty */
}
if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
FREE_OP2();
ZVAL_NULL(retval);
@ -1347,7 +1353,7 @@ ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV)
container = GET_OP1_OBJ_ZVAL_PTR_DEREF(BP_VAR_R);
offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
if ((OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
zend_error(E_NOTICE, "Trying to get property of non-object");
ZVAL_NULL(EX_VAR(opline->result.var));
@ -1383,7 +1389,7 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
FREE_OP2();
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@ -1407,7 +1413,7 @@ ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
FREE_OP2();
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@ -1429,7 +1435,7 @@ ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV
container = GET_OP1_OBJ_ZVAL_PTR_DEREF(BP_VAR_IS);
offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
if ((OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
ZVAL_NULL(EX_VAR(opline->result.var));
} else {
@ -1469,7 +1475,7 @@ ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
FREE_OP2();
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@ -1495,7 +1501,7 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
FREE_OP2();
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@ -1552,7 +1558,7 @@ ZEND_VM_HANDLER(136, ZEND_ASSIGN_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
if (OP1_TYPE == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, OP1_TYPE, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
FREE_OP2();
FREE_OP1_VAR_PTR();
/* assign_obj has two opcodes! */
@ -1580,7 +1586,7 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
zend_free_op free_op2;
zval *property_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, OP1_TYPE, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
FREE_OP2();
} else {
zend_free_op free_op2, free_op_data1, free_op_data2;
@ -2139,7 +2145,7 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV)
object = GET_OP1_OBJ_ZVAL_PTR_DEREF(BP_VAR_R);
if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
uint32_t nesting = 1;
if (UNEXPECTED(EG(exception) != NULL)) {
@ -3725,7 +3731,7 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMP|VAR|UNUSED|CV, ANY)
obj = GET_OP1_OBJ_ZVAL_PTR_DEREF(BP_VAR_R);
if (OP1_TYPE == IS_CONST ||
UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT)) {
(OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) {
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@ -4312,71 +4318,66 @@ ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
}
offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
switch (Z_TYPE_P(container)) {
case IS_ARRAY: {
HashTable *ht = Z_ARRVAL_P(container);
if (OP1_TYPE != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
HashTable *ht = Z_ARRVAL_P(container);
ZEND_VM_C_LABEL(offset_again):
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
zend_hash_index_del(ht, hval);
break;
case IS_LONG:
hval = Z_LVAL_P(offset);
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
zend_hash_index_del(ht, hval);
break;
case IS_LONG:
hval = Z_LVAL_P(offset);
ZEND_VM_C_LABEL(num_index_dim):
zend_hash_index_del(ht, hval);
break;
case IS_STRING:
if (OP2_TYPE != IS_CONST) {
if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) {
ZEND_VM_C_GOTO(num_index_dim);
}
zend_hash_index_del(ht, hval);
break;
case IS_STRING:
if (OP2_TYPE != IS_CONST) {
if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) {
ZEND_VM_C_GOTO(num_index_dim);
}
if (ht == &EG(symbol_table).ht) {
zend_delete_global_variable(Z_STR_P(offset) TSRMLS_CC);
} else {
zend_hash_del(ht, Z_STR_P(offset));
}
break;
case IS_NULL:
zend_hash_del(ht, STR_EMPTY_ALLOC());
break;
case IS_FALSE:
hval = 0;
ZEND_VM_C_GOTO(num_index_dim);
case IS_TRUE:
hval = 1;
ZEND_VM_C_GOTO(num_index_dim);
case IS_RESOURCE:
hval = Z_RES_HANDLE_P(offset);
ZEND_VM_C_GOTO(num_index_dim);
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
ZEND_VM_C_GOTO(offset_again);
break;
default:
zend_error(E_WARNING, "Illegal offset type in unset");
break;
}
FREE_OP2();
break;
}
if (ht == &EG(symbol_table).ht) {
zend_delete_global_variable(Z_STR_P(offset) TSRMLS_CC);
} else {
zend_hash_del(ht, Z_STR_P(offset));
}
break;
case IS_NULL:
zend_hash_del(ht, STR_EMPTY_ALLOC());
break;
case IS_FALSE:
hval = 0;
ZEND_VM_C_GOTO(num_index_dim);
case IS_TRUE:
hval = 1;
ZEND_VM_C_GOTO(num_index_dim);
case IS_RESOURCE:
hval = Z_RES_HANDLE_P(offset);
ZEND_VM_C_GOTO(num_index_dim);
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
ZEND_VM_C_GOTO(offset_again);
break;
default:
zend_error(E_WARNING, "Illegal offset type in unset");
break;
}
case IS_OBJECT:
if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use object as array");
}
//??? if (OP2_TYPE == IS_CONST) {
//??? zval_copy_ctor(offset);
//??? }
Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC);
FREE_OP2();
break;
case IS_STRING:
zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
ZEND_VM_CONTINUE(); /* bailed out before */
default:
FREE_OP2();
break;
FREE_OP2();
} else if (OP1_TYPE == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use object as array");
}
//??? if (OP2_TYPE == IS_CONST) {
//??? zval_copy_ctor(offset);
//??? }
Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC);
FREE_OP2();
} else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
ZEND_VM_CONTINUE(); /* bailed out before */
} else {
FREE_OP2();
}
FREE_OP1_VAR_PTR();
CHECK_EXCEPTION();
@ -4398,7 +4399,7 @@ ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
ZVAL_DEREF(container);
if (Z_TYPE_P(container) == IS_OBJECT) {
if (OP1_TYPE == IS_UNUSED || Z_TYPE_P(container) == IS_OBJECT) {
if (Z_OBJ_HT_P(container)->unset_property) {
Z_OBJ_HT_P(container)->unset_property(container, offset, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC);
} else {
@ -4933,7 +4934,7 @@ ZEND_VM_HANDLER(115, ZEND_ISSET_ISEMPTY_DIM_OBJ, CONST|TMP|VAR|UNUSED|CV, CONST|
container = GET_OP1_OBJ_ZVAL_PTR_DEREF(BP_VAR_IS);
offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
if (Z_TYPE_P(container) == IS_ARRAY) {
if (OP1_TYPE != IS_UNUSED && Z_TYPE_P(container) == IS_ARRAY) {
HashTable *ht = Z_ARRVAL_P(container);
zval *value;
zend_string *str;
@ -4986,7 +4987,7 @@ ZEND_VM_C_LABEL(num_index_prop):
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
result = (value == NULL || !i_zend_is_true(value TSRMLS_CC));
}
} else if (Z_TYPE_P(container) == IS_OBJECT) {
} else if (OP1_TYPE == IS_UNUSED || Z_TYPE_P(container) == IS_OBJECT) {
if (Z_OBJ_HT_P(container)->has_dimension) {
result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0 TSRMLS_CC);
} else {
@ -5046,7 +5047,7 @@ ZEND_VM_HANDLER(148, ZEND_ISSET_ISEMPTY_PROP_OBJ, CONST|TMP|VAR|UNUSED|CV, CONST
container = GET_OP1_OBJ_ZVAL_PTR_DEREF(BP_VAR_IS);
offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
if (Z_TYPE_P(container) == IS_OBJECT) {
if (OP1_TYPE == IS_UNUSED || Z_TYPE_P(container) == IS_OBJECT) {
if (Z_OBJ_HT_P(container)->has_property) {
result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC);
} else {

File diff suppressed because it is too large Load Diff