diff options
Diffstat (limited to 'Zend/zend_vm_def.h')
| -rw-r--r-- | Zend/zend_vm_def.h | 114 |
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 { |
