summaryrefslogtreecommitdiff
path: root/Zend/zend_vm_def.h
diff options
context:
space:
mode:
Diffstat (limited to 'Zend/zend_vm_def.h')
-rw-r--r--Zend/zend_vm_def.h114
1 files changed, 54 insertions, 60 deletions
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index c0f6e40916..6028add427 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -347,7 +347,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR|
}
do {
- value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
if (UNEXPECTED(!make_real_object(&object TSRMLS_CC))) {
@@ -360,8 +360,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR|
}
/* here we are sure we are dealing with an object */
- if (opline->extended_value == ZEND_ASSIGN_OBJ
- && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
&& EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
ZVAL_DEREF(zptr);
@@ -372,19 +371,11 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR|
ZVAL_COPY(EX_VAR(opline->result.var), zptr);
}
} else {
- zval *z = NULL;
+ zval *z;
zval rv;
- if (opline->extended_value == ZEND_ASSIGN_OBJ) {
- if (Z_OBJ_HT_P(object)->read_property) {
- z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
- }
- } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
- if (Z_OBJ_HT_P(object)->read_dimension) {
- z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R, &rv TSRMLS_CC);
- }
- }
- if (z) {
+ if (Z_OBJ_HT_P(object)->read_property &&
+ (z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC)) != NULL) {
if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
zval rv;
zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC);
@@ -394,14 +385,10 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR|
}
ZVAL_COPY_VALUE(z, value);
}
-//??? if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z);
- SEPARATE_ZVAL_IF_NOT_REF(z);
+ ZVAL_DEREF(z);
+ SEPARATE_ZVAL_NOREF(z);
binary_op(z, z, value TSRMLS_CC);
- if (opline->extended_value == ZEND_ASSIGN_OBJ) {
- Z_OBJ_HT_P(object)->write_property(object, property, z, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
- Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
- }
+ Z_OBJ_HT_P(object)->write_property(object, property, z, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), z);
}
@@ -434,44 +421,47 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_dim_helper, VAR|UNUSED|CV, CONST|TMPVAR|
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (OP1_TYPE != IS_UNUSED) {
- ZVAL_DEREF(container);
- }
-
-#if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
- 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() */
- }
- ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, binary_op);
- }
-#endif
dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
- zend_fetch_dimension_address_RW(&rv, container, dim, OP2_TYPE TSRMLS_CC);
- value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
- var_ptr = Z_INDIRECT(rv);
+ do {
+ if (OP1_TYPE == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) != IS_ARRAY)) {
+ if (OP1_TYPE != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+#if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
+ if (OP1_TYPE == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op TSRMLS_CC);
+ break;
+ }
+#endif
+ }
- if (UNEXPECTED(var_ptr == NULL)) {
- zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");
- }
+ zend_fetch_dimension_address_RW(&rv, container, dim, OP2_TYPE TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
- if (UNEXPECTED(var_ptr == &EG(error_zval))) {
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_NULL(EX_VAR(opline->result.var));
+ if (UNEXPECTED(var_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");
}
- } else {
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
- binary_op(var_ptr, var_ptr, value TSRMLS_CC);
+ if (UNEXPECTED(var_ptr == &EG(error_zval))) {
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_NULL(EX_VAR(opline->result.var));
+ }
+ } else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ binary_op(var_ptr, var_ptr, value TSRMLS_CC);
+
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
- }
+ } while (0);
FREE_OP2();
FREE_OP(free_op_data1);
@@ -793,12 +783,13 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|C
}
ZVAL_COPY_VALUE(z, value);
}
- if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z);
- SEPARATE_ZVAL_IF_NOT_REF(z);
+ ZVAL_DEREF(z);
+ SEPARATE_ZVAL_NOREF(z);
incdec_op(z);
- ZVAL_COPY_VALUE(retval, z);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, z);
+ }
Z_OBJ_HT_P(object)->write_property(object, property, z, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- SELECTIVE_PZVAL_LOCK(retval, opline);
zval_ptr_dtor(z);
} else {
zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
@@ -4486,15 +4477,15 @@ ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|UNUSED|CV, CONST|TMPVAR|CV)
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
}
- if (OP1_TYPE != IS_UNUSED) {
- ZVAL_DEREF(container);
- }
- SEPARATE_ZVAL_NOREF(container);
offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
+ZEND_VM_C_LABEL(unset_dim_again):
if (OP1_TYPE != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
- HashTable *ht = Z_ARRVAL_P(container);
+ HashTable *ht;
+
ZEND_VM_C_LABEL(offset_again):
+ SEPARATE_ARRAY(container);
+ ht = Z_ARRVAL_P(container);
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -4547,7 +4538,10 @@ ZEND_VM_C_LABEL(num_index_dim):
//??? }
Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC);
FREE_OP2();
- } else if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
+ } else if (OP1_TYPE != IS_UNUSED && Z_ISREF_P(container)) {
+ container = Z_REFVAL_P(container);
+ ZEND_VM_C_GOTO(unset_dim_again);
+ } else if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
ZEND_VM_CONTINUE(); /* bailed out before */
} else {