From: Dmitry Stogov Date: Fri, 10 Oct 2014 12:36:12 +0000 (+0400) Subject: Improved specialisation $this variable accessed through IS_UNUSED operand must be... X-Git-Tag: POST_NATIVE_TLS_MERGE^2~76^2~4 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=af3354dc43ae3c4bc6c9a9fb74aee2d9c2f406e3;p=php 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. --- diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index fa5de685c9..a3f18b960f 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -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; - - 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 (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 */ + 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; - - ZVAL_DEREF(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - if (UNEXPECTED(container == &EG(error_zval))) { - ZVAL_INDIRECT(result, &EG(error_zval)); - return; - } + 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; + } - /* 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) { diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 8c59b4ec38..736ce178d6 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -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); - } - } - 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)); + 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); } - 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 { diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index d31fcdc740..af0cd96bbf 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -2782,7 +2782,7 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS obj = opline->op1.zv; if (IS_CONST == IS_CONST || - UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT)) { + (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) { if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -3968,7 +3968,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_ container = opline->op1.zv; offset = opline->op2.zv; - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_CONST != 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)); @@ -4000,7 +4000,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE container = opline->op1.zv; offset = opline->op2.zv; - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_CONST != 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 { @@ -4039,7 +4039,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST_HANDLER(ZEND_ if (IS_CONST == 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, ((IS_CONST == 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, IS_CONST, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -4659,7 +4659,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CONST_HANDLER(ZE container = opline->op1.zv; offset = opline->op2.zv; - if (Z_TYPE_P(container) == IS_ARRAY) { + if (IS_CONST != IS_UNUSED && Z_TYPE_P(container) == IS_ARRAY) { HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; @@ -4712,7 +4712,7 @@ 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 (IS_CONST == 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 { @@ -4771,7 +4771,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CONST_HANDLER(Z container = opline->op1.zv; offset = opline->op2.zv; - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_CONST == 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, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { @@ -5321,7 +5321,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HA container = opline->op1.zv; offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_CONST != 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)); @@ -5354,7 +5354,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_H container = opline->op1.zv; offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_CONST != 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 { @@ -5394,7 +5394,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMP_HANDLER(ZEND_OP if (IS_CONST == 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, ((IS_TMP_VAR == 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, IS_CONST, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -5733,7 +5733,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMP_HANDLER(ZEND container = opline->op1.zv; offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (Z_TYPE_P(container) == IS_ARRAY) { + if (IS_CONST != IS_UNUSED && Z_TYPE_P(container) == IS_ARRAY) { HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; @@ -5786,7 +5786,7 @@ 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 (IS_CONST == 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 { @@ -5846,7 +5846,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMP_HANDLER(ZEN container = opline->op1.zv; offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_CONST == 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, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { @@ -6515,7 +6515,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HA container = opline->op1.zv; offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_CONST != 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)); @@ -6548,7 +6548,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_H container = opline->op1.zv; offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_CONST != 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 { @@ -6588,7 +6588,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_VAR_HANDLER(ZEND_OP if (IS_CONST == 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, ((IS_VAR == 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, IS_CONST, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -7081,7 +7081,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_VAR_HANDLER(ZEND container = opline->op1.zv; offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (Z_TYPE_P(container) == IS_ARRAY) { + if (IS_CONST != IS_UNUSED && Z_TYPE_P(container) == IS_ARRAY) { HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; @@ -7134,7 +7134,7 @@ 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 (IS_CONST == 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 { @@ -7194,7 +7194,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_VAR_HANDLER(ZEN container = opline->op1.zv; offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_CONST == 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, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { @@ -8450,7 +8450,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HAN container = opline->op1.zv; offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_CONST != 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)); @@ -8482,7 +8482,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HA container = opline->op1.zv; offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_CONST != 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 { @@ -8521,7 +8521,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV_HANDLER(ZEND_OPC if (IS_CONST == 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, ((IS_CV == 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, IS_CONST, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -8911,7 +8911,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CV_HANDLER(ZEND_ container = opline->op1.zv; offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (Z_TYPE_P(container) == IS_ARRAY) { + if (IS_CONST != IS_UNUSED && Z_TYPE_P(container) == IS_ARRAY) { HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; @@ -8964,7 +8964,7 @@ 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 (IS_CONST == 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 { @@ -9023,7 +9023,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CV_HANDLER(ZEND container = opline->op1.zv; offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_CONST == 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, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { @@ -9598,7 +9598,7 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) obj = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); if (IS_TMP_VAR == IS_CONST || - UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT)) { + (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) { if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -10804,7 +10804,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HA container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = opline->op2.zv; - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_TMP_VAR != 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)); @@ -10836,7 +10836,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_H container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = opline->op2.zv; - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_TMP_VAR != 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 { @@ -10875,7 +10875,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OP if (IS_TMP_VAR == 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, ((IS_CONST == 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, IS_TMP_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -10983,7 +10983,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST_HANDLER(ZEND_OPCO object = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { uint32_t nesting = 1; if (UNEXPECTED(EG(exception) != NULL)) { @@ -11366,7 +11366,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CONST_HANDLER(ZEND container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = opline->op2.zv; - if (Z_TYPE_P(container) == IS_ARRAY) { + if (IS_TMP_VAR != IS_UNUSED && Z_TYPE_P(container) == IS_ARRAY) { HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; @@ -11419,7 +11419,7 @@ 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 (IS_TMP_VAR == 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 { @@ -11478,7 +11478,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CONST_HANDLER(ZEN container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = opline->op2.zv; - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_TMP_VAR == 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, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { @@ -11995,7 +11995,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HAND container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_TMP_VAR != 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)); @@ -12028,7 +12028,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HAN container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_TMP_VAR != 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 { @@ -12068,7 +12068,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMP_HANDLER(ZEND_OPCO if (IS_TMP_VAR == 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, ((IS_TMP_VAR == 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, IS_TMP_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -12149,7 +12149,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE object = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { uint32_t nesting = 1; if (UNEXPECTED(EG(exception) != NULL)) { @@ -12380,7 +12380,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_TMP_HANDLER(ZEND_O container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (Z_TYPE_P(container) == IS_ARRAY) { + if (IS_TMP_VAR != IS_UNUSED && Z_TYPE_P(container) == IS_ARRAY) { HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; @@ -12433,7 +12433,7 @@ 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 (IS_TMP_VAR == 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 { @@ -12493,7 +12493,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_TMP_HANDLER(ZEND_ container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_TMP_VAR == 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, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { @@ -13162,7 +13162,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HAND container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_TMP_VAR != 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)); @@ -13195,7 +13195,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HAN container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_TMP_VAR != 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 { @@ -13235,7 +13235,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_VAR_HANDLER(ZEND_OPCO if (IS_TMP_VAR == 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, ((IS_VAR == 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, IS_TMP_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -13316,7 +13316,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE object = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { uint32_t nesting = 1; if (UNEXPECTED(EG(exception) != NULL)) { @@ -13701,7 +13701,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_VAR_HANDLER(ZEND_O container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (Z_TYPE_P(container) == IS_ARRAY) { + if (IS_TMP_VAR != IS_UNUSED && Z_TYPE_P(container) == IS_ARRAY) { HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; @@ -13754,7 +13754,7 @@ 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 (IS_TMP_VAR == 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 { @@ -13814,7 +13814,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_VAR_HANDLER(ZEND_ container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_TMP_VAR == 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, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { @@ -14921,7 +14921,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDL container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_TMP_VAR != 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)); @@ -14953,7 +14953,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HAND container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_TMP_VAR != 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 { @@ -14992,7 +14992,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCOD if (IS_TMP_VAR == 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, ((IS_CV == 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, IS_TMP_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -15072,7 +15072,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_ object = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { uint32_t nesting = 1; if (UNEXPECTED(EG(exception) != NULL)) { @@ -15301,7 +15301,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CV_HANDLER(ZEND_OP container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (Z_TYPE_P(container) == IS_ARRAY) { + if (IS_TMP_VAR != IS_UNUSED && Z_TYPE_P(container) == IS_ARRAY) { HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; @@ -15354,7 +15354,7 @@ 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 (IS_TMP_VAR == 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 { @@ -15413,7 +15413,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CV_HANDLER(ZEND_O container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_TMP_VAR == 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, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { @@ -16319,7 +16319,7 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) obj = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); if (IS_VAR == IS_CONST || - UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT)) { + (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) { if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -17539,11 +17539,13 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - object = make_real_object(object TSRMLS_CC); + if (IS_VAR != 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 (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to assign property of non-object"); FREE_OP(free_op_data1); @@ -17632,7 +17634,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CONST(int (*b container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); if (IS_VAR == 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 (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) { Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */ } @@ -17896,9 +17898,11 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t 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 (IS_VAR != 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 (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (RETURN_VALUE_USED(opline)) { @@ -17987,9 +17991,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_ 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 (IS_VAR != 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 (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); ZVAL_NULL(retval); @@ -18354,7 +18360,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = opline->op2.zv; - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_VAR != 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)); @@ -18389,7 +18395,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CONST == 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, IS_VAR, property, ((IS_CONST == 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); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -18413,7 +18419,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H if (IS_VAR == 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, ((IS_CONST == 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, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -18435,7 +18441,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = opline->op2.zv; - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_VAR != 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 { @@ -18474,7 +18480,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OP if (IS_VAR == 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, ((IS_CONST == 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, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -18500,7 +18506,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCOD if (IS_VAR == 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, ((IS_CONST == 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, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -18557,7 +18563,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN if (IS_VAR == 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, ((IS_CONST == 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, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; /* assign_obj has two opcodes! */ @@ -18585,7 +18591,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN zval *property_name = opline->op2.zv; - 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, ((IS_CONST == 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, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); } else { zend_free_op free_op_data1, free_op_data2; @@ -18681,7 +18687,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZEND_OPCO object = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { uint32_t nesting = 1; if (UNEXPECTED(EG(exception) != NULL)) { @@ -19213,71 +19219,66 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND } offset = opline->op2.zv; - switch (Z_TYPE_P(container)) { - case IS_ARRAY: { - HashTable *ht = Z_ARRVAL_P(container); + if (IS_VAR != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht = Z_ARRVAL_P(container); 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); num_index_dim: - zend_hash_index_del(ht, hval); - break; - case IS_STRING: - if (IS_CONST != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { - 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)); + zend_hash_index_del(ht, hval); + break; + case IS_STRING: + if (IS_CONST != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { + goto num_index_dim; } - break; - case IS_NULL: - zend_hash_del(ht, STR_EMPTY_ALLOC()); - break; - case IS_FALSE: - hval = 0; - goto num_index_dim; - case IS_TRUE: - hval = 1; - goto num_index_dim; - case IS_RESOURCE: - hval = Z_RES_HANDLE_P(offset); - goto num_index_dim; - case IS_REFERENCE: - offset = Z_REFVAL_P(offset); - goto offset_again; - break; - default: - zend_error(E_WARNING, "Illegal offset type in unset"); - 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; + goto num_index_dim; + case IS_TRUE: + hval = 1; + goto num_index_dim; + case IS_RESOURCE: + hval = Z_RES_HANDLE_P(offset); + goto num_index_dim; + case IS_REFERENCE: + offset = Z_REFVAL_P(offset); + goto offset_again; + break; + default: + zend_error(E_WARNING, "Illegal offset type in unset"); + break; + } - break; + } else if (IS_VAR == 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"); } - case IS_OBJECT: - if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { - zend_error_noreturn(E_ERROR, "Cannot use object as array"); - } -//??? if (IS_CONST == IS_CONST) { -//??? zval_copy_ctor(offset); -//??? } - Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC); +//??? if (IS_CONST == IS_CONST) { +//??? zval_copy_ctor(offset); +//??? } + Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC); - break; - case IS_STRING: - zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); - ZEND_VM_CONTINUE(); /* bailed out before */ - default: + } 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 { - break; } if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; CHECK_EXCEPTION(); @@ -19299,7 +19300,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND offset = opline->op2.zv; ZVAL_DEREF(container); - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_VAR == 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, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { @@ -19404,7 +19405,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_VAR_CONST_HANDLER(ZEND container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = opline->op2.zv; - if (Z_TYPE_P(container) == IS_ARRAY) { + if (IS_VAR != IS_UNUSED && Z_TYPE_P(container) == IS_ARRAY) { HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; @@ -19457,7 +19458,7 @@ 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 (IS_VAR == 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 { @@ -19516,7 +19517,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_CONST_HANDLER(ZEN container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = opline->op2.zv; - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_VAR == 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, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { @@ -19975,11 +19976,13 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - object = make_real_object(object TSRMLS_CC); + if (IS_VAR != 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 (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to assign property of non-object"); zval_ptr_dtor_nogc(free_op2.var); FREE_OP(free_op_data1); @@ -20069,7 +20072,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_TMP(int (*bin container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); if (IS_VAR == 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 (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) { Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */ } @@ -20333,9 +20336,11 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMP(incdec_t i 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 (IS_VAR != 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 (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); zval_ptr_dtor_nogc(free_op2.var); if (RETURN_VALUE_USED(opline)) { @@ -20425,9 +20430,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMP(incdec_t 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 (IS_VAR != 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 (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); zval_ptr_dtor_nogc(free_op2.var); ZVAL_NULL(retval); @@ -20642,7 +20649,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_VAR != 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)); @@ -20678,7 +20685,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_TMP_VAR == 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, IS_VAR, property, ((IS_TMP_VAR == 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); zval_ptr_dtor_nogc(free_op2.var); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -20702,7 +20709,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN if (IS_VAR == 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, ((IS_TMP_VAR == 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, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -20724,7 +20731,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_VAR != 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 { @@ -20764,7 +20771,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCO if (IS_VAR == 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, ((IS_TMP_VAR == 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, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -20790,7 +20797,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_ if (IS_VAR == 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, ((IS_TMP_VAR == 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, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -20814,7 +20821,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL if (IS_VAR == 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, ((IS_TMP_VAR == 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, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; /* assign_obj has two opcodes! */ @@ -20842,7 +20849,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL zend_free_op free_op2; zval *property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - 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, ((IS_TMP_VAR == 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, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); } else { zend_free_op free_op2, free_op_data1, free_op_data2; @@ -20938,7 +20945,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE object = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { uint32_t nesting = 1; if (UNEXPECTED(EG(exception) != NULL)) { @@ -21301,71 +21308,66 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLE } offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - switch (Z_TYPE_P(container)) { - case IS_ARRAY: { - HashTable *ht = Z_ARRVAL_P(container); + if (IS_VAR != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht = Z_ARRVAL_P(container); 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); num_index_dim: - zend_hash_index_del(ht, hval); - break; - case IS_STRING: - if (IS_TMP_VAR != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { - 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)); + zend_hash_index_del(ht, hval); + break; + case IS_STRING: + if (IS_TMP_VAR != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { + goto num_index_dim; } - break; - case IS_NULL: - zend_hash_del(ht, STR_EMPTY_ALLOC()); - break; - case IS_FALSE: - hval = 0; - goto num_index_dim; - case IS_TRUE: - hval = 1; - goto num_index_dim; - case IS_RESOURCE: - hval = Z_RES_HANDLE_P(offset); - goto num_index_dim; - case IS_REFERENCE: - offset = Z_REFVAL_P(offset); - goto offset_again; - break; - default: - zend_error(E_WARNING, "Illegal offset type in unset"); - break; - } - zval_ptr_dtor_nogc(free_op2.var); - 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; + goto num_index_dim; + case IS_TRUE: + hval = 1; + goto num_index_dim; + case IS_RESOURCE: + hval = Z_RES_HANDLE_P(offset); + goto num_index_dim; + case IS_REFERENCE: + offset = Z_REFVAL_P(offset); + 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 (IS_TMP_VAR == IS_CONST) { -//??? zval_copy_ctor(offset); -//??? } - Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - break; - case IS_STRING: - zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); - ZEND_VM_CONTINUE(); /* bailed out before */ - default: - zval_ptr_dtor_nogc(free_op2.var); - break; + zval_ptr_dtor_nogc(free_op2.var); + } else if (IS_VAR == 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 (IS_TMP_VAR == IS_CONST) { +//??? zval_copy_ctor(offset); +//??? } + Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2.var); + } 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 { + zval_ptr_dtor_nogc(free_op2.var); } if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; CHECK_EXCEPTION(); @@ -21387,7 +21389,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLE offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); ZVAL_DEREF(container); - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_VAR == 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, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { @@ -21413,7 +21415,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_O container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (Z_TYPE_P(container) == IS_ARRAY) { + if (IS_VAR != IS_UNUSED && Z_TYPE_P(container) == IS_ARRAY) { HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; @@ -21466,7 +21468,7 @@ 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 (IS_VAR == 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 { @@ -21526,7 +21528,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_ container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_VAR == 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, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { @@ -21986,11 +21988,13 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - object = make_real_object(object TSRMLS_CC); + if (IS_VAR != 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 (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to assign property of non-object"); zval_ptr_dtor_nogc(free_op2.var); FREE_OP(free_op_data1); @@ -22080,7 +22084,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_VAR(int (*bin container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); if (IS_VAR == 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 (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) { Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */ } @@ -22344,9 +22348,11 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_VAR(incdec_t i 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 (IS_VAR != 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 (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); zval_ptr_dtor_nogc(free_op2.var); if (RETURN_VALUE_USED(opline)) { @@ -22436,9 +22442,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_VAR(incdec_t 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 (IS_VAR != 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 (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); zval_ptr_dtor_nogc(free_op2.var); ZVAL_NULL(retval); @@ -22804,7 +22812,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_VAR != 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)); @@ -22840,7 +22848,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_VAR == 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, IS_VAR, property, ((IS_VAR == 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); zval_ptr_dtor_nogc(free_op2.var); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -22864,7 +22872,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN if (IS_VAR == 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, ((IS_VAR == 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, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -22886,7 +22894,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_VAR != 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 { @@ -22926,7 +22934,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCO if (IS_VAR == 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, ((IS_VAR == 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, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -22952,7 +22960,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_ if (IS_VAR == 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, ((IS_VAR == 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, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -22976,7 +22984,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL if (IS_VAR == 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, ((IS_VAR == 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, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; /* assign_obj has two opcodes! */ @@ -23004,7 +23012,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL zend_free_op free_op2; zval *property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - 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, ((IS_VAR == 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, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); } else { zend_free_op free_op2, free_op_data1, free_op_data2; @@ -23164,7 +23172,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE object = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { uint32_t nesting = 1; if (UNEXPECTED(EG(exception) != NULL)) { @@ -23602,71 +23610,66 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE } offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - switch (Z_TYPE_P(container)) { - case IS_ARRAY: { - HashTable *ht = Z_ARRVAL_P(container); + if (IS_VAR != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht = Z_ARRVAL_P(container); 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); num_index_dim: - zend_hash_index_del(ht, hval); - break; - case IS_STRING: - if (IS_VAR != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { - 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)); + zend_hash_index_del(ht, hval); + break; + case IS_STRING: + if (IS_VAR != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { + goto num_index_dim; } - break; - case IS_NULL: - zend_hash_del(ht, STR_EMPTY_ALLOC()); - break; - case IS_FALSE: - hval = 0; - goto num_index_dim; - case IS_TRUE: - hval = 1; - goto num_index_dim; - case IS_RESOURCE: - hval = Z_RES_HANDLE_P(offset); - goto num_index_dim; - case IS_REFERENCE: - offset = Z_REFVAL_P(offset); - goto offset_again; - break; - default: - zend_error(E_WARNING, "Illegal offset type in unset"); - break; - } - zval_ptr_dtor_nogc(free_op2.var); - 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; + goto num_index_dim; + case IS_TRUE: + hval = 1; + goto num_index_dim; + case IS_RESOURCE: + hval = Z_RES_HANDLE_P(offset); + goto num_index_dim; + case IS_REFERENCE: + offset = Z_REFVAL_P(offset); + 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 (IS_VAR == IS_CONST) { -//??? zval_copy_ctor(offset); -//??? } - Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - break; - case IS_STRING: - zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); - ZEND_VM_CONTINUE(); /* bailed out before */ - default: - zval_ptr_dtor_nogc(free_op2.var); - break; + zval_ptr_dtor_nogc(free_op2.var); + } else if (IS_VAR == 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 (IS_VAR == IS_CONST) { +//??? zval_copy_ctor(offset); +//??? } + Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2.var); + } 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 { + zval_ptr_dtor_nogc(free_op2.var); } if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; CHECK_EXCEPTION(); @@ -23688,7 +23691,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); ZVAL_DEREF(container); - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_VAR == 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, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { @@ -23793,7 +23796,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_O container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (Z_TYPE_P(container) == IS_ARRAY) { + if (IS_VAR != IS_UNUSED && Z_TYPE_P(container) == IS_ARRAY) { HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; @@ -23846,7 +23849,7 @@ 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 (IS_VAR == 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 { @@ -23906,7 +23909,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_ container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_VAR == 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, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { @@ -24091,11 +24094,13 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (* zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - object = make_real_object(object TSRMLS_CC); + if (IS_VAR != 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 (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to assign property of non-object"); FREE_OP(free_op_data1); @@ -24184,7 +24189,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_UNUSED(int (* container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); if (IS_VAR == 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 (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) { Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */ } @@ -24683,7 +24688,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA zval *property_name = NULL; - 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, ((IS_UNUSED == 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, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_UNUSED == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); } else { zend_free_op free_op_data1, free_op_data2; @@ -25562,11 +25567,13 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - object = make_real_object(object TSRMLS_CC); + if (IS_VAR != 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 (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to assign property of non-object"); FREE_OP(free_op_data1); @@ -25655,7 +25662,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CV(int (*bina container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); if (IS_VAR == 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 (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) { Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */ } @@ -25919,9 +25926,11 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t in 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 (IS_VAR != 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 (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (RETURN_VALUE_USED(opline)) { @@ -26010,9 +26019,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t i 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 (IS_VAR != 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 (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); ZVAL_NULL(retval); @@ -26226,7 +26237,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_VAR != 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)); @@ -26261,7 +26272,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CV == 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, IS_VAR, property, ((IS_CV == 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); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -26285,7 +26296,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND if (IS_VAR == 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, ((IS_CV == 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, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -26307,7 +26318,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_VAR != 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 { @@ -26346,7 +26357,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCOD if (IS_VAR == 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, ((IS_CV == 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, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -26372,7 +26383,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_H if (IS_VAR == 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, ((IS_CV == 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, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -26396,7 +26407,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE if (IS_VAR == 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, ((IS_CV == 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, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; /* assign_obj has two opcodes! */ @@ -26424,7 +26435,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE zval *property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - 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, ((IS_CV == 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, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); } else { zend_free_op free_op_data1, free_op_data2; @@ -26582,7 +26593,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_ object = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { uint32_t nesting = 1; if (UNEXPECTED(EG(exception) != NULL)) { @@ -26943,71 +26954,66 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER } offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - switch (Z_TYPE_P(container)) { - case IS_ARRAY: { - HashTable *ht = Z_ARRVAL_P(container); + if (IS_VAR != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht = Z_ARRVAL_P(container); 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); num_index_dim: - zend_hash_index_del(ht, hval); - break; - case IS_STRING: - if (IS_CV != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { - 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)); + zend_hash_index_del(ht, hval); + break; + case IS_STRING: + if (IS_CV != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { + goto num_index_dim; } - break; - case IS_NULL: - zend_hash_del(ht, STR_EMPTY_ALLOC()); - break; - case IS_FALSE: - hval = 0; - goto num_index_dim; - case IS_TRUE: - hval = 1; - goto num_index_dim; - case IS_RESOURCE: - hval = Z_RES_HANDLE_P(offset); - goto num_index_dim; - case IS_REFERENCE: - offset = Z_REFVAL_P(offset); - goto offset_again; - break; - default: - zend_error(E_WARNING, "Illegal offset type in unset"); - 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; + goto num_index_dim; + case IS_TRUE: + hval = 1; + goto num_index_dim; + case IS_RESOURCE: + hval = Z_RES_HANDLE_P(offset); + goto num_index_dim; + case IS_REFERENCE: + offset = Z_REFVAL_P(offset); + goto offset_again; + break; + default: + zend_error(E_WARNING, "Illegal offset type in unset"); + break; + } - break; + } else if (IS_VAR == 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"); } - case IS_OBJECT: - if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { - zend_error_noreturn(E_ERROR, "Cannot use object as array"); - } -//??? if (IS_CV == IS_CONST) { -//??? zval_copy_ctor(offset); -//??? } - Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC); +//??? if (IS_CV == IS_CONST) { +//??? zval_copy_ctor(offset); +//??? } + Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC); - break; - case IS_STRING: - zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); - ZEND_VM_CONTINUE(); /* bailed out before */ - default: + } 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 { - break; } if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; CHECK_EXCEPTION(); @@ -27029,7 +27035,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); ZVAL_DEREF(container); - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_VAR == 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, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { @@ -27055,7 +27061,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OP container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (Z_TYPE_P(container) == IS_ARRAY) { + if (IS_VAR != IS_UNUSED && Z_TYPE_P(container) == IS_ARRAY) { HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; @@ -27108,7 +27114,7 @@ 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 (IS_VAR == 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 { @@ -27167,7 +27173,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_CV_HANDLER(ZEND_O container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_VAR == 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, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { @@ -27351,7 +27357,7 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARG obj = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); if (IS_UNUSED == IS_CONST || - UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT)) { + (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) { if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -27431,11 +27437,13 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - object = make_real_object(object TSRMLS_CC); + if (IS_UNUSED != 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 (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to assign property of non-object"); FREE_OP(free_op_data1); @@ -27523,7 +27531,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CONST(int container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); if (IS_UNUSED == 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 (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (IS_UNUSED == IS_VAR && !0) { Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */ } @@ -27787,9 +27795,11 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(incde 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 (IS_UNUSED != 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 (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (RETURN_VALUE_USED(opline)) { @@ -27878,9 +27888,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CONST(incd 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 (IS_UNUSED != 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 (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); ZVAL_NULL(retval); @@ -27959,7 +27971,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); offset = opline->op2.zv; - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_UNUSED != 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)); @@ -27994,7 +28006,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CONST == 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, IS_UNUSED, property, ((IS_CONST == 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); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -28018,7 +28030,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCOD if (IS_UNUSED == 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, ((IS_CONST == 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, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -28040,7 +28052,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCOD container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); offset = opline->op2.zv; - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_UNUSED != 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 { @@ -28079,7 +28091,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST_HANDLER(ZEND if (IS_UNUSED == 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, ((IS_CONST == 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, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -28105,7 +28117,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST_HANDLER(ZEND_OP if (IS_UNUSED == 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, ((IS_CONST == 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, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -28129,7 +28141,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_ if (IS_UNUSED == 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, ((IS_CONST == 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, IS_UNUSED, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); /* assign_obj has two opcodes! */ @@ -28200,7 +28212,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_O object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { uint32_t nesting = 1; if (UNEXPECTED(EG(exception) != NULL)) { @@ -28428,71 +28440,66 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_H } offset = opline->op2.zv; - switch (Z_TYPE_P(container)) { - case IS_ARRAY: { - HashTable *ht = Z_ARRVAL_P(container); + if (IS_UNUSED != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht = Z_ARRVAL_P(container); 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); num_index_dim: - zend_hash_index_del(ht, hval); - break; - case IS_STRING: - if (IS_CONST != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { - 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)); + zend_hash_index_del(ht, hval); + break; + case IS_STRING: + if (IS_CONST != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { + goto num_index_dim; } - break; - case IS_NULL: - zend_hash_del(ht, STR_EMPTY_ALLOC()); - break; - case IS_FALSE: - hval = 0; - goto num_index_dim; - case IS_TRUE: - hval = 1; - goto num_index_dim; - case IS_RESOURCE: - hval = Z_RES_HANDLE_P(offset); - goto num_index_dim; - case IS_REFERENCE: - offset = Z_REFVAL_P(offset); - goto offset_again; - break; - default: - zend_error(E_WARNING, "Illegal offset type in unset"); - 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; + goto num_index_dim; + case IS_TRUE: + hval = 1; + goto num_index_dim; + case IS_RESOURCE: + hval = Z_RES_HANDLE_P(offset); + goto num_index_dim; + case IS_REFERENCE: + offset = Z_REFVAL_P(offset); + goto offset_again; + break; + default: + zend_error(E_WARNING, "Illegal offset type in unset"); + break; + } - break; + } else if (IS_UNUSED == 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"); } - case IS_OBJECT: - if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { - zend_error_noreturn(E_ERROR, "Cannot use object as array"); - } -//??? if (IS_CONST == IS_CONST) { -//??? zval_copy_ctor(offset); -//??? } - Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC); +//??? if (IS_CONST == IS_CONST) { +//??? zval_copy_ctor(offset); +//??? } + Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC); - break; - case IS_STRING: - zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); - ZEND_VM_CONTINUE(); /* bailed out before */ - default: + } 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 { - break; } CHECK_EXCEPTION(); @@ -28514,7 +28521,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_H offset = opline->op2.zv; ZVAL_DEREF(container); - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_UNUSED == 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, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { @@ -28540,7 +28547,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNUSED_CONST_HANDLER(Z container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); offset = opline->op2.zv; - if (Z_TYPE_P(container) == IS_ARRAY) { + if (IS_UNUSED != IS_UNUSED && Z_TYPE_P(container) == IS_ARRAY) { HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; @@ -28593,7 +28600,7 @@ 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 (IS_UNUSED == 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 { @@ -28652,7 +28659,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST_HANDLER( container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); offset = opline->op2.zv; - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_UNUSED == 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, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { @@ -28820,11 +28827,13 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (* zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - object = make_real_object(object TSRMLS_CC); + if (IS_UNUSED != 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 (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to assign property of non-object"); zval_ptr_dtor_nogc(free_op2.var); FREE_OP(free_op_data1); @@ -28913,7 +28922,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_TMP(int (* container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); if (IS_UNUSED == 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 (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (IS_UNUSED == IS_VAR && !0) { Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */ } @@ -29177,9 +29186,11 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_TMP(incdec_ 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 (IS_UNUSED != 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 (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); zval_ptr_dtor_nogc(free_op2.var); if (RETURN_VALUE_USED(opline)) { @@ -29269,9 +29280,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_TMP(incdec 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 (IS_UNUSED != 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 (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); zval_ptr_dtor_nogc(free_op2.var); ZVAL_NULL(retval); @@ -29351,7 +29364,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_H container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_UNUSED != 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)); @@ -29387,7 +29400,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_H zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_TMP_VAR == 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, IS_UNUSED, property, ((IS_TMP_VAR == 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); zval_ptr_dtor_nogc(free_op2.var); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -29411,7 +29424,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_ if (IS_UNUSED == 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, ((IS_TMP_VAR == 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, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -29433,7 +29446,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_ container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_UNUSED != 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 { @@ -29473,7 +29486,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP_HANDLER(ZEND_O if (IS_UNUSED == 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, ((IS_TMP_VAR == 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, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -29499,7 +29512,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCO if (IS_UNUSED == 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, ((IS_TMP_VAR == 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, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -29523,7 +29536,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HA if (IS_UNUSED == 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, ((IS_TMP_VAR == 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, IS_UNUSED, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); /* assign_obj has two opcodes! */ @@ -29600,7 +29613,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP_HANDLER(ZEND_OPC object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { uint32_t nesting = 1; if (UNEXPECTED(EG(exception) != NULL)) { @@ -29733,71 +29746,66 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HAN } offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - switch (Z_TYPE_P(container)) { - case IS_ARRAY: { - HashTable *ht = Z_ARRVAL_P(container); + if (IS_UNUSED != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht = Z_ARRVAL_P(container); 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); num_index_dim: - zend_hash_index_del(ht, hval); - break; - case IS_STRING: - if (IS_TMP_VAR != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { - 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)); + zend_hash_index_del(ht, hval); + break; + case IS_STRING: + if (IS_TMP_VAR != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { + goto num_index_dim; } - break; - case IS_NULL: - zend_hash_del(ht, STR_EMPTY_ALLOC()); - break; - case IS_FALSE: - hval = 0; - goto num_index_dim; - case IS_TRUE: - hval = 1; - goto num_index_dim; - case IS_RESOURCE: - hval = Z_RES_HANDLE_P(offset); - goto num_index_dim; - case IS_REFERENCE: - offset = Z_REFVAL_P(offset); - goto offset_again; - break; - default: - zend_error(E_WARNING, "Illegal offset type in unset"); - break; - } - zval_ptr_dtor_nogc(free_op2.var); - 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; + goto num_index_dim; + case IS_TRUE: + hval = 1; + goto num_index_dim; + case IS_RESOURCE: + hval = Z_RES_HANDLE_P(offset); + goto num_index_dim; + case IS_REFERENCE: + offset = Z_REFVAL_P(offset); + 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 (IS_TMP_VAR == IS_CONST) { -//??? zval_copy_ctor(offset); -//??? } - Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - break; - case IS_STRING: - zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); - ZEND_VM_CONTINUE(); /* bailed out before */ - default: - zval_ptr_dtor_nogc(free_op2.var); - break; + zval_ptr_dtor_nogc(free_op2.var); + } else if (IS_UNUSED == 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 (IS_TMP_VAR == IS_CONST) { +//??? zval_copy_ctor(offset); +//??? } + Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2.var); + } 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 { + zval_ptr_dtor_nogc(free_op2.var); } CHECK_EXCEPTION(); @@ -29819,7 +29827,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HAN offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); ZVAL_DEREF(container); - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_UNUSED == 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, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { @@ -29845,7 +29853,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEN container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (Z_TYPE_P(container) == IS_ARRAY) { + if (IS_UNUSED != IS_UNUSED && Z_TYPE_P(container) == IS_ARRAY) { HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; @@ -29898,7 +29906,7 @@ 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 (IS_UNUSED == 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 { @@ -29958,7 +29966,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMP_HANDLER(ZE container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_UNUSED == 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, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { @@ -30127,11 +30135,13 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (* zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - object = make_real_object(object TSRMLS_CC); + if (IS_UNUSED != 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 (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to assign property of non-object"); zval_ptr_dtor_nogc(free_op2.var); FREE_OP(free_op_data1); @@ -30220,7 +30230,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_VAR(int (* container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); if (IS_UNUSED == 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 (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (IS_UNUSED == IS_VAR && !0) { Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */ } @@ -30484,9 +30494,11 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_VAR(incdec_ 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 (IS_UNUSED != 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 (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); zval_ptr_dtor_nogc(free_op2.var); if (RETURN_VALUE_USED(opline)) { @@ -30576,9 +30588,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_VAR(incdec 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 (IS_UNUSED != 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 (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); zval_ptr_dtor_nogc(free_op2.var); ZVAL_NULL(retval); @@ -30658,7 +30672,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_H container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_UNUSED != 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)); @@ -30694,7 +30708,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_H zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_VAR == 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, IS_UNUSED, property, ((IS_VAR == 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); zval_ptr_dtor_nogc(free_op2.var); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -30718,7 +30732,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_ if (IS_UNUSED == 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, ((IS_VAR == 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, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -30740,7 +30754,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_ container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_UNUSED != 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 { @@ -30780,7 +30794,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_VAR_HANDLER(ZEND_O if (IS_UNUSED == 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, ((IS_VAR == 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, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -30806,7 +30820,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCO if (IS_UNUSED == 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, ((IS_VAR == 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, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -30830,7 +30844,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HA if (IS_UNUSED == 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, ((IS_VAR == 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, IS_UNUSED, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); /* assign_obj has two opcodes! */ @@ -30907,7 +30921,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_VAR_HANDLER(ZEND_OPC object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { uint32_t nesting = 1; if (UNEXPECTED(EG(exception) != NULL)) { @@ -31040,71 +31054,66 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HAN } offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - switch (Z_TYPE_P(container)) { - case IS_ARRAY: { - HashTable *ht = Z_ARRVAL_P(container); + if (IS_UNUSED != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht = Z_ARRVAL_P(container); 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); num_index_dim: - zend_hash_index_del(ht, hval); - break; - case IS_STRING: - if (IS_VAR != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { - 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)); + zend_hash_index_del(ht, hval); + break; + case IS_STRING: + if (IS_VAR != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { + goto num_index_dim; } - break; - case IS_NULL: - zend_hash_del(ht, STR_EMPTY_ALLOC()); - break; - case IS_FALSE: - hval = 0; - goto num_index_dim; - case IS_TRUE: - hval = 1; - goto num_index_dim; - case IS_RESOURCE: - hval = Z_RES_HANDLE_P(offset); - goto num_index_dim; - case IS_REFERENCE: - offset = Z_REFVAL_P(offset); - goto offset_again; - break; - default: - zend_error(E_WARNING, "Illegal offset type in unset"); - break; - } - zval_ptr_dtor_nogc(free_op2.var); - 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; + goto num_index_dim; + case IS_TRUE: + hval = 1; + goto num_index_dim; + case IS_RESOURCE: + hval = Z_RES_HANDLE_P(offset); + goto num_index_dim; + case IS_REFERENCE: + offset = Z_REFVAL_P(offset); + 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 (IS_VAR == IS_CONST) { -//??? zval_copy_ctor(offset); -//??? } - Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - break; - case IS_STRING: - zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); - ZEND_VM_CONTINUE(); /* bailed out before */ - default: - zval_ptr_dtor_nogc(free_op2.var); - break; + zval_ptr_dtor_nogc(free_op2.var); + } else if (IS_UNUSED == 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 (IS_VAR == IS_CONST) { +//??? zval_copy_ctor(offset); +//??? } + Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2.var); + } 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 { + zval_ptr_dtor_nogc(free_op2.var); } CHECK_EXCEPTION(); @@ -31126,7 +31135,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HAN offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); ZVAL_DEREF(container); - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_UNUSED == 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, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { @@ -31152,7 +31161,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEN container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (Z_TYPE_P(container) == IS_ARRAY) { + if (IS_UNUSED != IS_UNUSED && Z_TYPE_P(container) == IS_ARRAY) { HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; @@ -31205,7 +31214,7 @@ 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 (IS_UNUSED == 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 { @@ -31265,7 +31274,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_VAR_HANDLER(ZE container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_UNUSED == 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, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { @@ -31434,11 +31443,13 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - object = make_real_object(object TSRMLS_CC); + if (IS_UNUSED != 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 (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to assign property of non-object"); FREE_OP(free_op_data1); @@ -31526,7 +31537,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_UNUSED(int container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); if (IS_UNUSED == 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 (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (IS_UNUSED == IS_VAR && !0) { Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */ } @@ -31951,11 +31962,13 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - object = make_real_object(object TSRMLS_CC); + if (IS_UNUSED != 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 (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to assign property of non-object"); FREE_OP(free_op_data1); @@ -32043,7 +32056,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CV(int (*b container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); if (IS_UNUSED == 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 (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (IS_UNUSED == IS_VAR && !0) { Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */ } @@ -32307,9 +32320,11 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CV(incdec_t 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 (IS_UNUSED != 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 (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (RETURN_VALUE_USED(opline)) { @@ -32398,9 +32413,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CV(incdec_ 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 (IS_UNUSED != 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 (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); ZVAL_NULL(retval); @@ -32479,7 +32496,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HA container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_UNUSED != 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)); @@ -32514,7 +32531,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HA zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CV == 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, IS_UNUSED, property, ((IS_CV == 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); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -32538,7 +32555,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_H if (IS_UNUSED == 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, ((IS_CV == 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, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -32560,7 +32577,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_H container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_UNUSED != 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 { @@ -32599,7 +32616,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV_HANDLER(ZEND_OP if (IS_UNUSED == 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, ((IS_CV == 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, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -32625,7 +32642,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV_HANDLER(ZEND_OPCOD if (IS_UNUSED == 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, ((IS_CV == 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, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -32649,7 +32666,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAN if (IS_UNUSED == 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, ((IS_CV == 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, IS_UNUSED, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); /* assign_obj has two opcodes! */ @@ -32725,7 +32742,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCO object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { uint32_t nesting = 1; if (UNEXPECTED(EG(exception) != NULL)) { @@ -32857,71 +32874,66 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAND } offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - switch (Z_TYPE_P(container)) { - case IS_ARRAY: { - HashTable *ht = Z_ARRVAL_P(container); + if (IS_UNUSED != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht = Z_ARRVAL_P(container); 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); num_index_dim: - zend_hash_index_del(ht, hval); - break; - case IS_STRING: - if (IS_CV != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { - 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)); + zend_hash_index_del(ht, hval); + break; + case IS_STRING: + if (IS_CV != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { + goto num_index_dim; } - break; - case IS_NULL: - zend_hash_del(ht, STR_EMPTY_ALLOC()); - break; - case IS_FALSE: - hval = 0; - goto num_index_dim; - case IS_TRUE: - hval = 1; - goto num_index_dim; - case IS_RESOURCE: - hval = Z_RES_HANDLE_P(offset); - goto num_index_dim; - case IS_REFERENCE: - offset = Z_REFVAL_P(offset); - goto offset_again; - break; - default: - zend_error(E_WARNING, "Illegal offset type in unset"); - 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; + goto num_index_dim; + case IS_TRUE: + hval = 1; + goto num_index_dim; + case IS_RESOURCE: + hval = Z_RES_HANDLE_P(offset); + goto num_index_dim; + case IS_REFERENCE: + offset = Z_REFVAL_P(offset); + goto offset_again; + break; + default: + zend_error(E_WARNING, "Illegal offset type in unset"); + break; + } - break; + } else if (IS_UNUSED == 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"); } - case IS_OBJECT: - if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { - zend_error_noreturn(E_ERROR, "Cannot use object as array"); - } -//??? if (IS_CV == IS_CONST) { -//??? zval_copy_ctor(offset); -//??? } - Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC); +//??? if (IS_CV == IS_CONST) { +//??? zval_copy_ctor(offset); +//??? } + Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC); - break; - case IS_STRING: - zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); - ZEND_VM_CONTINUE(); /* bailed out before */ - default: + } 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 { - break; } CHECK_EXCEPTION(); @@ -32943,7 +32955,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAND offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); ZVAL_DEREF(container); - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_UNUSED == 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, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { @@ -32969,7 +32981,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (Z_TYPE_P(container) == IS_ARRAY) { + if (IS_UNUSED != IS_UNUSED && Z_TYPE_P(container) == IS_ARRAY) { HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; @@ -33022,7 +33034,7 @@ 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 (IS_UNUSED == 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 { @@ -33081,7 +33093,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV_HANDLER(ZEN container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_UNUSED == 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, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { @@ -33957,7 +33969,7 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) obj = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_CONST || - UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT)) { + (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) { if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -34931,11 +34943,13 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - object = make_real_object(object TSRMLS_CC); + if (IS_CV != 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 (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to assign property of non-object"); FREE_OP(free_op_data1); @@ -35023,7 +35037,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CONST(int (*bi container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == 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 (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (IS_CV == IS_VAR && !0) { Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */ } @@ -35287,9 +35301,11 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CONST(incdec_t 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 (IS_CV != 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 (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (RETURN_VALUE_USED(opline)) { @@ -35378,9 +35394,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CONST(incdec_t 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 (IS_CV != 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 (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); ZVAL_NULL(retval); @@ -35745,7 +35763,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN container = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); offset = opline->op2.zv; - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_CV != 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)); @@ -35780,7 +35798,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CONST == 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, IS_CV, property, ((IS_CONST == 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); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -35804,7 +35822,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA if (IS_CV == 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, ((IS_CONST == 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, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -35826,7 +35844,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA container = _get_zval_ptr_cv_deref_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); offset = opline->op2.zv; - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_CV != 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 { @@ -35865,7 +35883,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPC if (IS_CV == 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, ((IS_CONST == 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, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -35891,7 +35909,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE if (IS_CV == 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, ((IS_CONST == 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, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -35948,7 +35966,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND if (IS_CV == 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, ((IS_CONST == 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, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); /* assign_obj has two opcodes! */ @@ -35976,7 +35994,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND zval *property_name = opline->op2.zv; - 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, ((IS_CONST == 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, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); } else { zend_free_op free_op_data1, free_op_data2; @@ -36072,7 +36090,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_HANDLER(ZEND_OPCOD object = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { uint32_t nesting = 1; if (UNEXPECTED(EG(exception) != NULL)) { @@ -36382,71 +36400,66 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL } offset = opline->op2.zv; - switch (Z_TYPE_P(container)) { - case IS_ARRAY: { - HashTable *ht = Z_ARRVAL_P(container); + if (IS_CV != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht = Z_ARRVAL_P(container); 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); num_index_dim: - zend_hash_index_del(ht, hval); - break; - case IS_STRING: - if (IS_CONST != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { - 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)); + zend_hash_index_del(ht, hval); + break; + case IS_STRING: + if (IS_CONST != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { + goto num_index_dim; } - break; - case IS_NULL: - zend_hash_del(ht, STR_EMPTY_ALLOC()); - break; - case IS_FALSE: - hval = 0; - goto num_index_dim; - case IS_TRUE: - hval = 1; - goto num_index_dim; - case IS_RESOURCE: - hval = Z_RES_HANDLE_P(offset); - goto num_index_dim; - case IS_REFERENCE: - offset = Z_REFVAL_P(offset); - goto offset_again; - break; - default: - zend_error(E_WARNING, "Illegal offset type in unset"); - 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; + goto num_index_dim; + case IS_TRUE: + hval = 1; + goto num_index_dim; + case IS_RESOURCE: + hval = Z_RES_HANDLE_P(offset); + goto num_index_dim; + case IS_REFERENCE: + offset = Z_REFVAL_P(offset); + goto offset_again; + break; + default: + zend_error(E_WARNING, "Illegal offset type in unset"); + break; + } - break; + } else if (IS_CV == 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"); } - case IS_OBJECT: - if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { - zend_error_noreturn(E_ERROR, "Cannot use object as array"); - } -//??? if (IS_CONST == IS_CONST) { -//??? zval_copy_ctor(offset); -//??? } - Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC); +//??? if (IS_CONST == IS_CONST) { +//??? zval_copy_ctor(offset); +//??? } + Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC); - break; - case IS_STRING: - zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); - ZEND_VM_CONTINUE(); /* bailed out before */ - default: + } 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 { - break; } CHECK_EXCEPTION(); @@ -36468,7 +36481,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL offset = opline->op2.zv; ZVAL_DEREF(container); - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_CV == 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, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { @@ -36573,7 +36586,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST_HANDLER(ZEND_ container = _get_zval_ptr_cv_deref_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); offset = opline->op2.zv; - if (Z_TYPE_P(container) == IS_ARRAY) { + if (IS_CV != IS_UNUSED && Z_TYPE_P(container) == IS_ARRAY) { HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; @@ -36626,7 +36639,7 @@ 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 (IS_CV == 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 { @@ -36685,7 +36698,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST_HANDLER(ZEND container = _get_zval_ptr_cv_deref_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); offset = opline->op2.zv; - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_CV == 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, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { @@ -37200,11 +37213,13 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - object = make_real_object(object TSRMLS_CC); + if (IS_CV != 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 (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to assign property of non-object"); zval_ptr_dtor_nogc(free_op2.var); FREE_OP(free_op_data1); @@ -37293,7 +37308,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_TMP(int (*bina container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == 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 (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (IS_CV == IS_VAR && !0) { Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */ } @@ -37557,9 +37572,11 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_TMP(incdec_t in 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 (IS_CV != 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 (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); zval_ptr_dtor_nogc(free_op2.var); if (RETURN_VALUE_USED(opline)) { @@ -37649,9 +37666,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_TMP(incdec_t i 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 (IS_CV != 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 (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); zval_ptr_dtor_nogc(free_op2.var); ZVAL_NULL(retval); @@ -37866,7 +37885,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL container = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_CV != 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)); @@ -37902,7 +37921,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_TMP_VAR == 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, IS_CV, property, ((IS_TMP_VAR == 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); zval_ptr_dtor_nogc(free_op2.var); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -37926,7 +37945,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND if (IS_CV == 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, ((IS_TMP_VAR == 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, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -37948,7 +37967,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND container = _get_zval_ptr_cv_deref_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_CV != 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 { @@ -37988,7 +38007,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCOD if (IS_CV == 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, ((IS_TMP_VAR == 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, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -38014,7 +38033,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_H if (IS_CV == 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, ((IS_TMP_VAR == 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, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -38038,7 +38057,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE if (IS_CV == 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, ((IS_TMP_VAR == 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, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); /* assign_obj has two opcodes! */ @@ -38066,7 +38085,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE zend_free_op free_op2; zval *property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - 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, ((IS_TMP_VAR == 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, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); } else { zend_free_op free_op2, free_op_data1, free_op_data2; @@ -38162,7 +38181,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_ object = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { uint32_t nesting = 1; if (UNEXPECTED(EG(exception) != NULL)) { @@ -38399,71 +38418,66 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER } offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - switch (Z_TYPE_P(container)) { - case IS_ARRAY: { - HashTable *ht = Z_ARRVAL_P(container); + if (IS_CV != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht = Z_ARRVAL_P(container); 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); num_index_dim: - zend_hash_index_del(ht, hval); - break; - case IS_STRING: - if (IS_TMP_VAR != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { - 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)); + zend_hash_index_del(ht, hval); + break; + case IS_STRING: + if (IS_TMP_VAR != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { + goto num_index_dim; } - break; - case IS_NULL: - zend_hash_del(ht, STR_EMPTY_ALLOC()); - break; - case IS_FALSE: - hval = 0; - goto num_index_dim; - case IS_TRUE: - hval = 1; - goto num_index_dim; - case IS_RESOURCE: - hval = Z_RES_HANDLE_P(offset); - goto num_index_dim; - case IS_REFERENCE: - offset = Z_REFVAL_P(offset); - goto offset_again; - break; - default: - zend_error(E_WARNING, "Illegal offset type in unset"); - break; - } - zval_ptr_dtor_nogc(free_op2.var); - 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; + goto num_index_dim; + case IS_TRUE: + hval = 1; + goto num_index_dim; + case IS_RESOURCE: + hval = Z_RES_HANDLE_P(offset); + goto num_index_dim; + case IS_REFERENCE: + offset = Z_REFVAL_P(offset); + 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 (IS_TMP_VAR == IS_CONST) { -//??? zval_copy_ctor(offset); -//??? } - Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - break; - case IS_STRING: - zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); - ZEND_VM_CONTINUE(); /* bailed out before */ - default: - zval_ptr_dtor_nogc(free_op2.var); - break; + zval_ptr_dtor_nogc(free_op2.var); + } else if (IS_CV == 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 (IS_TMP_VAR == IS_CONST) { +//??? zval_copy_ctor(offset); +//??? } + Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2.var); + } 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 { + zval_ptr_dtor_nogc(free_op2.var); } CHECK_EXCEPTION(); @@ -38485,7 +38499,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); ZVAL_DEREF(container); - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_CV == 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, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { @@ -38511,7 +38525,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OP container = _get_zval_ptr_cv_deref_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (Z_TYPE_P(container) == IS_ARRAY) { + if (IS_CV != IS_UNUSED && Z_TYPE_P(container) == IS_ARRAY) { HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; @@ -38564,7 +38578,7 @@ 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 (IS_CV == 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 { @@ -38624,7 +38638,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMP_HANDLER(ZEND_O container = _get_zval_ptr_cv_deref_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_CV == 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, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { @@ -39083,11 +39097,13 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - object = make_real_object(object TSRMLS_CC); + if (IS_CV != 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 (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to assign property of non-object"); zval_ptr_dtor_nogc(free_op2.var); FREE_OP(free_op_data1); @@ -39176,7 +39192,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_VAR(int (*bina container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == 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 (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (IS_CV == IS_VAR && !0) { Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */ } @@ -39440,9 +39456,11 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_VAR(incdec_t in 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 (IS_CV != 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 (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); zval_ptr_dtor_nogc(free_op2.var); if (RETURN_VALUE_USED(opline)) { @@ -39532,9 +39550,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_VAR(incdec_t i 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 (IS_CV != 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 (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); zval_ptr_dtor_nogc(free_op2.var); ZVAL_NULL(retval); @@ -39900,7 +39920,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL container = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_CV != 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)); @@ -39936,7 +39956,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_VAR == 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, IS_CV, property, ((IS_VAR == 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); zval_ptr_dtor_nogc(free_op2.var); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -39960,7 +39980,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND if (IS_CV == 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, ((IS_VAR == 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, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -39982,7 +40002,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND container = _get_zval_ptr_cv_deref_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_CV != 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 { @@ -40022,7 +40042,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCOD if (IS_CV == 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, ((IS_VAR == 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, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -40048,7 +40068,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_H if (IS_CV == 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, ((IS_VAR == 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, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -40072,7 +40092,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE if (IS_CV == 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, ((IS_VAR == 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, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); /* assign_obj has two opcodes! */ @@ -40100,7 +40120,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE zend_free_op free_op2; zval *property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - 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, ((IS_VAR == 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, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); } else { zend_free_op free_op2, free_op_data1, free_op_data2; @@ -40259,7 +40279,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_ object = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { uint32_t nesting = 1; if (UNEXPECTED(EG(exception) != NULL)) { @@ -40571,71 +40591,66 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER } offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - switch (Z_TYPE_P(container)) { - case IS_ARRAY: { - HashTable *ht = Z_ARRVAL_P(container); + if (IS_CV != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht = Z_ARRVAL_P(container); 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); num_index_dim: - zend_hash_index_del(ht, hval); - break; - case IS_STRING: - if (IS_VAR != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { - 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)); + zend_hash_index_del(ht, hval); + break; + case IS_STRING: + if (IS_VAR != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { + goto num_index_dim; } - break; - case IS_NULL: - zend_hash_del(ht, STR_EMPTY_ALLOC()); - break; - case IS_FALSE: - hval = 0; - goto num_index_dim; - case IS_TRUE: - hval = 1; - goto num_index_dim; - case IS_RESOURCE: - hval = Z_RES_HANDLE_P(offset); - goto num_index_dim; - case IS_REFERENCE: - offset = Z_REFVAL_P(offset); - goto offset_again; - break; - default: - zend_error(E_WARNING, "Illegal offset type in unset"); - break; - } - zval_ptr_dtor_nogc(free_op2.var); - 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; + goto num_index_dim; + case IS_TRUE: + hval = 1; + goto num_index_dim; + case IS_RESOURCE: + hval = Z_RES_HANDLE_P(offset); + goto num_index_dim; + case IS_REFERENCE: + offset = Z_REFVAL_P(offset); + 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 (IS_VAR == IS_CONST) { -//??? zval_copy_ctor(offset); -//??? } - Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - break; - case IS_STRING: - zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); - ZEND_VM_CONTINUE(); /* bailed out before */ - default: - zval_ptr_dtor_nogc(free_op2.var); - break; + zval_ptr_dtor_nogc(free_op2.var); + } else if (IS_CV == 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 (IS_VAR == IS_CONST) { +//??? zval_copy_ctor(offset); +//??? } + Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2.var); + } 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 { + zval_ptr_dtor_nogc(free_op2.var); } CHECK_EXCEPTION(); @@ -40657,7 +40672,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); ZVAL_DEREF(container); - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_CV == 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, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { @@ -40762,7 +40777,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_VAR_HANDLER(ZEND_OP container = _get_zval_ptr_cv_deref_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (Z_TYPE_P(container) == IS_ARRAY) { + if (IS_CV != IS_UNUSED && Z_TYPE_P(container) == IS_ARRAY) { HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; @@ -40815,7 +40830,7 @@ 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 (IS_CV == 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 { @@ -40875,7 +40890,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_VAR_HANDLER(ZEND_O container = _get_zval_ptr_cv_deref_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_CV == 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, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { @@ -41059,11 +41074,13 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*b zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - object = make_real_object(object TSRMLS_CC); + if (IS_CV != 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 (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to assign property of non-object"); FREE_OP(free_op_data1); @@ -41151,7 +41168,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_UNUSED(int (*b container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == 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 (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (IS_CV == IS_VAR && !0) { Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */ } @@ -41650,7 +41667,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN zval *property_name = NULL; - 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, ((IS_UNUSED == 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, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_UNUSED == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); } else { zend_free_op free_op_data1, free_op_data2; @@ -42386,11 +42403,13 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - object = make_real_object(object TSRMLS_CC); + if (IS_CV != 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 (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to assign property of non-object"); FREE_OP(free_op_data1); @@ -42478,7 +42497,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CV(int (*binar container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == 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 (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (IS_CV == IS_VAR && !0) { Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */ } @@ -42742,9 +42761,11 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CV(incdec_t inc 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 (IS_CV != 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 (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (RETURN_VALUE_USED(opline)) { @@ -42833,9 +42854,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CV(incdec_t in 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 (IS_CV != 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 (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); ZVAL_NULL(retval); @@ -43049,7 +43072,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE container = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_CV != 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)); @@ -43084,7 +43107,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CV == 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, IS_CV, property, ((IS_CV == 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); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -43108,7 +43131,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL if (IS_CV == 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, ((IS_CV == 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, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -43130,7 +43153,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL container = _get_zval_ptr_cv_deref_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + if ((IS_CV != 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 { @@ -43169,7 +43192,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE if (IS_CV == 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, ((IS_CV == 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, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -43195,7 +43218,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HA if (IS_CV == 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, ((IS_CV == 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, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -43219,7 +43242,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER if (IS_CV == 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, ((IS_CV == 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, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); /* assign_obj has two opcodes! */ @@ -43247,7 +43270,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER zval *property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - 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, ((IS_CV == 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, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); } else { zend_free_op free_op_data1, free_op_data2; @@ -43404,7 +43427,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_H object = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { uint32_t nesting = 1; if (UNEXPECTED(EG(exception) != NULL)) { @@ -43639,71 +43662,66 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ } offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - switch (Z_TYPE_P(container)) { - case IS_ARRAY: { - HashTable *ht = Z_ARRVAL_P(container); + if (IS_CV != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht = Z_ARRVAL_P(container); 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); num_index_dim: - zend_hash_index_del(ht, hval); - break; - case IS_STRING: - if (IS_CV != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { - 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)); + zend_hash_index_del(ht, hval); + break; + case IS_STRING: + if (IS_CV != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) { + goto num_index_dim; } - break; - case IS_NULL: - zend_hash_del(ht, STR_EMPTY_ALLOC()); - break; - case IS_FALSE: - hval = 0; - goto num_index_dim; - case IS_TRUE: - hval = 1; - goto num_index_dim; - case IS_RESOURCE: - hval = Z_RES_HANDLE_P(offset); - goto num_index_dim; - case IS_REFERENCE: - offset = Z_REFVAL_P(offset); - goto offset_again; - break; - default: - zend_error(E_WARNING, "Illegal offset type in unset"); - 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; + goto num_index_dim; + case IS_TRUE: + hval = 1; + goto num_index_dim; + case IS_RESOURCE: + hval = Z_RES_HANDLE_P(offset); + goto num_index_dim; + case IS_REFERENCE: + offset = Z_REFVAL_P(offset); + goto offset_again; + break; + default: + zend_error(E_WARNING, "Illegal offset type in unset"); + break; + } - break; + } else if (IS_CV == 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"); } - case IS_OBJECT: - if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { - zend_error_noreturn(E_ERROR, "Cannot use object as array"); - } -//??? if (IS_CV == IS_CONST) { -//??? zval_copy_ctor(offset); -//??? } - Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC); +//??? if (IS_CV == IS_CONST) { +//??? zval_copy_ctor(offset); +//??? } + Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC); - break; - case IS_STRING: - zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); - ZEND_VM_CONTINUE(); /* bailed out before */ - default: + } 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 { - break; } CHECK_EXCEPTION(); @@ -43725,7 +43743,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); ZVAL_DEREF(container); - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_CV == 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, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else { @@ -43751,7 +43769,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPC container = _get_zval_ptr_cv_deref_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (Z_TYPE_P(container) == IS_ARRAY) { + if (IS_CV != IS_UNUSED && Z_TYPE_P(container) == IS_ARRAY) { HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; @@ -43804,7 +43822,7 @@ 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 (IS_CV == 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 { @@ -43863,7 +43881,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV_HANDLER(ZEND_OP container = _get_zval_ptr_cv_deref_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (Z_TYPE_P(container) == IS_OBJECT) { + if (IS_CV == 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, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC); } else {