mirror of
https://github.com/php/php-src.git
synced 2024-11-24 10:24:11 +08:00
Improved specialisation $this variable accessed through IS_UNUSED operand must be IS_OBJECT, so we don't have to check for its type or perform dereference.
This commit is contained in:
parent
3efc331701
commit
af3354dc43
@ -701,49 +701,50 @@ static void zend_verify_missing_arg(zend_execute_data *execute_data, uint32_t ar
|
||||
}
|
||||
}
|
||||
|
||||
static inline void zend_assign_to_object(zval *retval, zval *object_ptr, zval *property_name, int value_type, const znode_op *value_op, const zend_execute_data *execute_data, int opcode, void **cache_slot TSRMLS_DC)
|
||||
static zend_always_inline void zend_assign_to_object(zval *retval, zval *object, uint32_t object_op_type, zval *property_name, int value_type, const znode_op *value_op, const zend_execute_data *execute_data, int opcode, void **cache_slot TSRMLS_DC)
|
||||
{
|
||||
zend_free_op free_value;
|
||||
zval *value = get_zval_ptr(value_type, value_op, execute_data, &free_value, BP_VAR_R);
|
||||
zval tmp;
|
||||
zval *object = object_ptr;
|
||||
|
||||
ZVAL_DEREF(object);
|
||||
if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
|
||||
if (UNEXPECTED(object == &EG(error_zval))) {
|
||||
if (retval) {
|
||||
ZVAL_NULL(retval);
|
||||
if (object_op_type != IS_UNUSED) {
|
||||
ZVAL_DEREF(object);
|
||||
if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
|
||||
if (UNEXPECTED(object == &EG(error_zval))) {
|
||||
if (retval) {
|
||||
ZVAL_NULL(retval);
|
||||
}
|
||||
FREE_OP(free_value);
|
||||
return;
|
||||
}
|
||||
FREE_OP(free_value);
|
||||
return;
|
||||
}
|
||||
if (EXPECTED(Z_TYPE_P(object) == IS_NULL ||
|
||||
Z_TYPE_P(object) == IS_FALSE ||
|
||||
(Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) {
|
||||
zend_object *obj;
|
||||
if (EXPECTED(Z_TYPE_P(object) == IS_NULL ||
|
||||
Z_TYPE_P(object) == IS_FALSE ||
|
||||
(Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) {
|
||||
zend_object *obj;
|
||||
|
||||
zval_ptr_dtor(object);
|
||||
object_init(object);
|
||||
Z_ADDREF_P(object);
|
||||
obj = Z_OBJ_P(object);
|
||||
zend_error(E_WARNING, "Creating default object from empty value");
|
||||
if (GC_REFCOUNT(obj) == 1) {
|
||||
/* the enclosing container was deleted, obj is unreferenced */
|
||||
zval_ptr_dtor(object);
|
||||
object_init(object);
|
||||
Z_ADDREF_P(object);
|
||||
obj = Z_OBJ_P(object);
|
||||
zend_error(E_WARNING, "Creating default object from empty value");
|
||||
if (GC_REFCOUNT(obj) == 1) {
|
||||
/* the enclosing container was deleted, obj is unreferenced */
|
||||
if (retval) {
|
||||
ZVAL_NULL(retval);
|
||||
}
|
||||
FREE_OP(free_value);
|
||||
OBJ_RELEASE(obj);
|
||||
return;
|
||||
}
|
||||
Z_DELREF_P(object);
|
||||
} else {
|
||||
zend_error(E_WARNING, "Attempt to assign property of non-object");
|
||||
if (retval) {
|
||||
ZVAL_NULL(retval);
|
||||
}
|
||||
FREE_OP(free_value);
|
||||
OBJ_RELEASE(obj);
|
||||
return;
|
||||
}
|
||||
Z_DELREF_P(object);
|
||||
} else {
|
||||
zend_error(E_WARNING, "Attempt to assign property of non-object");
|
||||
if (retval) {
|
||||
ZVAL_NULL(retval);
|
||||
}
|
||||
FREE_OP(free_value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1301,31 +1302,30 @@ ZEND_API void zend_fetch_dimension_by_zval(zval *result, zval *container, zval *
|
||||
zend_fetch_dimension_address_read_R(result, container, dim, IS_TMP_VAR TSRMLS_CC);
|
||||
}
|
||||
|
||||
static void zend_fetch_property_address(zval *result, zval *container_ptr, zval *prop_ptr, void **cache_slot, int type, int is_ref TSRMLS_DC)
|
||||
static zend_always_inline void zend_fetch_property_address(zval *result, zval *container, uint32_t container_op_type, zval *prop_ptr, void **cache_slot, int type, int is_ref TSRMLS_DC)
|
||||
{
|
||||
zval *container = container_ptr;
|
||||
if (container_op_type != IS_UNUSED) {
|
||||
ZVAL_DEREF(container);
|
||||
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
|
||||
if (UNEXPECTED(container == &EG(error_zval))) {
|
||||
ZVAL_INDIRECT(result, &EG(error_zval));
|
||||
return;
|
||||
}
|
||||
|
||||
ZVAL_DEREF(container);
|
||||
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
|
||||
if (UNEXPECTED(container == &EG(error_zval))) {
|
||||
ZVAL_INDIRECT(result, &EG(error_zval));
|
||||
return;
|
||||
}
|
||||
|
||||
/* this should modify object only if it's empty */
|
||||
if (type != BP_VAR_UNSET &&
|
||||
EXPECTED((Z_TYPE_P(container) == IS_NULL ||
|
||||
Z_TYPE_P(container) == IS_FALSE ||
|
||||
(Z_TYPE_P(container) == IS_STRING && Z_STRLEN_P(container)==0)))) {
|
||||
zval_ptr_dtor_nogc(container);
|
||||
object_init(container);
|
||||
} else {
|
||||
zend_error(E_WARNING, "Attempt to modify property of non-object");
|
||||
ZVAL_INDIRECT(result, &EG(error_zval));
|
||||
return;
|
||||
/* this should modify object only if it's empty */
|
||||
if (type != BP_VAR_UNSET &&
|
||||
EXPECTED((Z_TYPE_P(container) == IS_NULL ||
|
||||
Z_TYPE_P(container) == IS_FALSE ||
|
||||
(Z_TYPE_P(container) == IS_STRING && Z_STRLEN_P(container)==0)))) {
|
||||
zval_ptr_dtor_nogc(container);
|
||||
object_init(container);
|
||||
} else {
|
||||
zend_error(E_WARNING, "Attempt to modify property of non-object");
|
||||
ZVAL_INDIRECT(result, &EG(error_zval));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (EXPECTED(Z_OBJ_HT_P(container)->get_property_ptr_ptr)) {
|
||||
zval *ptr = Z_OBJ_HT_P(container)->get_property_ptr_ptr(container, prop_ptr, type, cache_slot TSRMLS_CC);
|
||||
if (NULL == ptr) {
|
||||
|
@ -339,11 +339,13 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR
|
||||
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
|
||||
}
|
||||
|
||||
object = make_real_object(object TSRMLS_CC);
|
||||
if (OP1_TYPE != IS_UNUSED) {
|
||||
object = make_real_object(object TSRMLS_CC);
|
||||
}
|
||||
|
||||
value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
|
||||
|
||||
if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
|
||||
if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
|
||||
zend_error(E_WARNING, "Attempt to assign property of non-object");
|
||||
FREE_OP2();
|
||||
FREE_OP(free_op_data1);
|
||||
@ -433,7 +435,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_dim_helper, VAR|UNUSED|CV, CONST|TMP|VAR
|
||||
container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW);
|
||||
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
|
||||
} else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
|
||||
} else if (OP1_TYPE == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
|
||||
if (OP1_TYPE == IS_VAR && !OP1_FREE) {
|
||||
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
|
||||
}
|
||||
@ -697,9 +699,11 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR|
|
||||
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
|
||||
}
|
||||
|
||||
object = make_real_object(object TSRMLS_CC); /* this should modify object only if it's empty */
|
||||
if (OP1_TYPE != IS_UNUSED) {
|
||||
object = make_real_object(object TSRMLS_CC); /* this should modify object only if it's empty */
|
||||
}
|
||||
|
||||
if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
|
||||
if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
|
||||
zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
|
||||
FREE_OP2();
|
||||
if (RETURN_VALUE_USED(opline)) {
|
||||
@ -789,9 +793,11 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR
|
||||
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
|
||||
}
|
||||
|
||||
object = make_real_object(object TSRMLS_CC); /* this should modify object only if it's empty */
|
||||
if (OP1_TYPE != IS_UNUSED) {
|
||||
object = make_real_object(object TSRMLS_CC); /* this should modify object only if it's empty */
|
||||
}
|
||||
|
||||
if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
|
||||
if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
|
||||
zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
|
||||
FREE_OP2();
|
||||
ZVAL_NULL(retval);
|
||||
@ -1347,7 +1353,7 @@ ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV)
|
||||
container = GET_OP1_OBJ_ZVAL_PTR_DEREF(BP_VAR_R);
|
||||
offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
|
||||
|
||||
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
|
||||
if ((OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) ||
|
||||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
|
||||
zend_error(E_NOTICE, "Trying to get property of non-object");
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
@ -1383,7 +1389,7 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
|
||||
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
|
||||
}
|
||||
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
|
||||
FREE_OP2();
|
||||
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
|
||||
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
|
||||
@ -1407,7 +1413,7 @@ ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
|
||||
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
|
||||
}
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
|
||||
FREE_OP2();
|
||||
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
|
||||
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
|
||||
@ -1429,7 +1435,7 @@ ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV
|
||||
container = GET_OP1_OBJ_ZVAL_PTR_DEREF(BP_VAR_IS);
|
||||
offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
|
||||
|
||||
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
|
||||
if ((OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) ||
|
||||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
} else {
|
||||
@ -1469,7 +1475,7 @@ ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|
|
||||
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
|
||||
}
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
|
||||
FREE_OP2();
|
||||
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
|
||||
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
|
||||
@ -1495,7 +1501,7 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
|
||||
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
|
||||
}
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
|
||||
FREE_OP2();
|
||||
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
|
||||
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
|
||||
@ -1552,7 +1558,7 @@ ZEND_VM_HANDLER(136, ZEND_ASSIGN_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
|
||||
if (OP1_TYPE == IS_VAR && UNEXPECTED(object == NULL)) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
|
||||
}
|
||||
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
|
||||
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, OP1_TYPE, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
|
||||
FREE_OP2();
|
||||
FREE_OP1_VAR_PTR();
|
||||
/* assign_obj has two opcodes! */
|
||||
@ -1580,7 +1586,7 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
|
||||
zend_free_op free_op2;
|
||||
zval *property_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
|
||||
|
||||
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
|
||||
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, OP1_TYPE, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
|
||||
FREE_OP2();
|
||||
} else {
|
||||
zend_free_op free_op2, free_op_data1, free_op_data2;
|
||||
@ -2139,7 +2145,7 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV)
|
||||
|
||||
object = GET_OP1_OBJ_ZVAL_PTR_DEREF(BP_VAR_R);
|
||||
|
||||
if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
|
||||
if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
|
||||
uint32_t nesting = 1;
|
||||
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
@ -3725,7 +3731,7 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMP|VAR|UNUSED|CV, ANY)
|
||||
obj = GET_OP1_OBJ_ZVAL_PTR_DEREF(BP_VAR_R);
|
||||
|
||||
if (OP1_TYPE == IS_CONST ||
|
||||
UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT)) {
|
||||
(OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) {
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
@ -4312,71 +4318,66 @@ ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
|
||||
}
|
||||
offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
|
||||
|
||||
switch (Z_TYPE_P(container)) {
|
||||
case IS_ARRAY: {
|
||||
HashTable *ht = Z_ARRVAL_P(container);
|
||||
if (OP1_TYPE != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
|
||||
HashTable *ht = Z_ARRVAL_P(container);
|
||||
ZEND_VM_C_LABEL(offset_again):
|
||||
switch (Z_TYPE_P(offset)) {
|
||||
case IS_DOUBLE:
|
||||
hval = zend_dval_to_lval(Z_DVAL_P(offset));
|
||||
zend_hash_index_del(ht, hval);
|
||||
break;
|
||||
case IS_LONG:
|
||||
hval = Z_LVAL_P(offset);
|
||||
switch (Z_TYPE_P(offset)) {
|
||||
case IS_DOUBLE:
|
||||
hval = zend_dval_to_lval(Z_DVAL_P(offset));
|
||||
zend_hash_index_del(ht, hval);
|
||||
break;
|
||||
case IS_LONG:
|
||||
hval = Z_LVAL_P(offset);
|
||||
ZEND_VM_C_LABEL(num_index_dim):
|
||||
zend_hash_index_del(ht, hval);
|
||||
break;
|
||||
case IS_STRING:
|
||||
if (OP2_TYPE != IS_CONST) {
|
||||
if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) {
|
||||
ZEND_VM_C_GOTO(num_index_dim);
|
||||
}
|
||||
zend_hash_index_del(ht, hval);
|
||||
break;
|
||||
case IS_STRING:
|
||||
if (OP2_TYPE != IS_CONST) {
|
||||
if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) {
|
||||
ZEND_VM_C_GOTO(num_index_dim);
|
||||
}
|
||||
if (ht == &EG(symbol_table).ht) {
|
||||
zend_delete_global_variable(Z_STR_P(offset) TSRMLS_CC);
|
||||
} else {
|
||||
zend_hash_del(ht, Z_STR_P(offset));
|
||||
}
|
||||
break;
|
||||
case IS_NULL:
|
||||
zend_hash_del(ht, STR_EMPTY_ALLOC());
|
||||
break;
|
||||
case IS_FALSE:
|
||||
hval = 0;
|
||||
ZEND_VM_C_GOTO(num_index_dim);
|
||||
case IS_TRUE:
|
||||
hval = 1;
|
||||
ZEND_VM_C_GOTO(num_index_dim);
|
||||
case IS_RESOURCE:
|
||||
hval = Z_RES_HANDLE_P(offset);
|
||||
ZEND_VM_C_GOTO(num_index_dim);
|
||||
case IS_REFERENCE:
|
||||
offset = Z_REFVAL_P(offset);
|
||||
ZEND_VM_C_GOTO(offset_again);
|
||||
break;
|
||||
default:
|
||||
zend_error(E_WARNING, "Illegal offset type in unset");
|
||||
break;
|
||||
}
|
||||
FREE_OP2();
|
||||
break;
|
||||
}
|
||||
if (ht == &EG(symbol_table).ht) {
|
||||
zend_delete_global_variable(Z_STR_P(offset) TSRMLS_CC);
|
||||
} else {
|
||||
zend_hash_del(ht, Z_STR_P(offset));
|
||||
}
|
||||
break;
|
||||
case IS_NULL:
|
||||
zend_hash_del(ht, STR_EMPTY_ALLOC());
|
||||
break;
|
||||
case IS_FALSE:
|
||||
hval = 0;
|
||||
ZEND_VM_C_GOTO(num_index_dim);
|
||||
case IS_TRUE:
|
||||
hval = 1;
|
||||
ZEND_VM_C_GOTO(num_index_dim);
|
||||
case IS_RESOURCE:
|
||||
hval = Z_RES_HANDLE_P(offset);
|
||||
ZEND_VM_C_GOTO(num_index_dim);
|
||||
case IS_REFERENCE:
|
||||
offset = Z_REFVAL_P(offset);
|
||||
ZEND_VM_C_GOTO(offset_again);
|
||||
break;
|
||||
default:
|
||||
zend_error(E_WARNING, "Illegal offset type in unset");
|
||||
break;
|
||||
}
|
||||
case IS_OBJECT:
|
||||
if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot use object as array");
|
||||
}
|
||||
//??? if (OP2_TYPE == IS_CONST) {
|
||||
//??? zval_copy_ctor(offset);
|
||||
//??? }
|
||||
Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC);
|
||||
FREE_OP2();
|
||||
break;
|
||||
case IS_STRING:
|
||||
zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
|
||||
ZEND_VM_CONTINUE(); /* bailed out before */
|
||||
default:
|
||||
FREE_OP2();
|
||||
break;
|
||||
FREE_OP2();
|
||||
} else if (OP1_TYPE == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
|
||||
if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot use object as array");
|
||||
}
|
||||
//??? if (OP2_TYPE == IS_CONST) {
|
||||
//??? zval_copy_ctor(offset);
|
||||
//??? }
|
||||
Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC);
|
||||
FREE_OP2();
|
||||
} else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
|
||||
ZEND_VM_CONTINUE(); /* bailed out before */
|
||||
} else {
|
||||
FREE_OP2();
|
||||
}
|
||||
FREE_OP1_VAR_PTR();
|
||||
CHECK_EXCEPTION();
|
||||
@ -4398,7 +4399,7 @@ ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
|
||||
offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
|
||||
|
||||
ZVAL_DEREF(container);
|
||||
if (Z_TYPE_P(container) == IS_OBJECT) {
|
||||
if (OP1_TYPE == IS_UNUSED || Z_TYPE_P(container) == IS_OBJECT) {
|
||||
if (Z_OBJ_HT_P(container)->unset_property) {
|
||||
Z_OBJ_HT_P(container)->unset_property(container, offset, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC);
|
||||
} else {
|
||||
@ -4933,7 +4934,7 @@ ZEND_VM_HANDLER(115, ZEND_ISSET_ISEMPTY_DIM_OBJ, CONST|TMP|VAR|UNUSED|CV, CONST|
|
||||
container = GET_OP1_OBJ_ZVAL_PTR_DEREF(BP_VAR_IS);
|
||||
offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
|
||||
|
||||
if (Z_TYPE_P(container) == IS_ARRAY) {
|
||||
if (OP1_TYPE != IS_UNUSED && Z_TYPE_P(container) == IS_ARRAY) {
|
||||
HashTable *ht = Z_ARRVAL_P(container);
|
||||
zval *value;
|
||||
zend_string *str;
|
||||
@ -4986,7 +4987,7 @@ ZEND_VM_C_LABEL(num_index_prop):
|
||||
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
|
||||
result = (value == NULL || !i_zend_is_true(value TSRMLS_CC));
|
||||
}
|
||||
} else if (Z_TYPE_P(container) == IS_OBJECT) {
|
||||
} else if (OP1_TYPE == IS_UNUSED || Z_TYPE_P(container) == IS_OBJECT) {
|
||||
if (Z_OBJ_HT_P(container)->has_dimension) {
|
||||
result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0 TSRMLS_CC);
|
||||
} else {
|
||||
@ -5046,7 +5047,7 @@ ZEND_VM_HANDLER(148, ZEND_ISSET_ISEMPTY_PROP_OBJ, CONST|TMP|VAR|UNUSED|CV, CONST
|
||||
container = GET_OP1_OBJ_ZVAL_PTR_DEREF(BP_VAR_IS);
|
||||
offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
|
||||
|
||||
if (Z_TYPE_P(container) == IS_OBJECT) {
|
||||
if (OP1_TYPE == IS_UNUSED || Z_TYPE_P(container) == IS_OBJECT) {
|
||||
if (Z_OBJ_HT_P(container)->has_property) {
|
||||
result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC);
|
||||
} else {
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user