]> granicus.if.org Git - php/commitdiff
Merge branch 'PHP-7.4'
authorDmitry Stogov <dmitry@zend.com>
Fri, 15 Feb 2019 14:52:59 +0000 (17:52 +0300)
committerDmitry Stogov <dmitry@zend.com>
Fri, 15 Feb 2019 14:52:59 +0000 (17:52 +0300)
* PHP-7.4:
  Avoid useless code duplication, because of unused specialization

1  2 
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

Simple merge
index ab6ada935d8b6d94c41b76094ddef725c02e5131,72b98dc1bd4e1b2f218b0191df466706317d6327..576872d18b924ccfc8a743aaa288d6f6b873b52d
@@@ -44006,32 -41507,24 +42281,33 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS
                        }
                }
  
- post_incdec_object:
+ pre_incdec_object:
                /* here we are sure we are dealing with an object */
 +              zobj = Z_OBJ_P(object);
 +              if (IS_CONST == IS_CONST) {
 +                      name = Z_STR_P(property);
 +              } else {
 +                      name = zval_get_tmp_string(property, &tmp_name);
 +              }
                cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL;
 -              if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, cache_slot)) != NULL)) {
 +              if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
                        if (UNEXPECTED(Z_ISERROR_P(zptr))) {
-                               ZVAL_NULL(EX_VAR(opline->result.var));
+                               if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+                                       ZVAL_NULL(EX_VAR(opline->result.var));
+                               }
                        } else {
                                if (IS_CONST == IS_CONST) {
-                                       prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
+                                       prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2);
                                } else {
                                        prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), zptr);
                                }
-                               zend_post_incdec_property_zval(zptr, prop_info, inc OPLINE_CC EXECUTE_DATA_CC);
+                               zend_pre_incdec_property_zval(zptr, prop_info, inc OPLINE_CC EXECUTE_DATA_CC);
                        }
                } else {
-                       zend_post_incdec_overloaded_property(zobj, name, cache_slot, inc OPLINE_CC EXECUTE_DATA_CC);
 -                      zend_pre_incdec_overloaded_property(object, property, cache_slot, inc OPLINE_CC EXECUTE_DATA_CC);
++                      zend_pre_incdec_overloaded_property(zobj, name, cache_slot, inc OPLINE_CC EXECUTE_DATA_CC);
 +              }
 +              if (IS_CONST != IS_CONST) {
 +                      zend_tmp_string_release(tmp_name);
                }
        } while (0);
  
        ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
  }
  
- static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
  {
-       ZEND_VM_TAIL_CALL(zend_post_incdec_property_helper_SPEC_CV_CONST(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
+       ZEND_VM_TAIL_CALL(zend_pre_incdec_property_helper_SPEC_CV_CONST(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
  }
  
- static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
  {
-       ZEND_VM_TAIL_CALL(zend_post_incdec_property_helper_SPEC_CV_CONST(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
+       ZEND_VM_TAIL_CALL(zend_pre_incdec_property_helper_SPEC_CV_CONST(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
  }
  
- static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_static_property_helper_SPEC_CV_CONST(int inc ZEND_OPCODE_HANDLER_ARGS_DC)
+ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CONST(int inc ZEND_OPCODE_HANDLER_ARGS_DC)
  {
        USE_OPLINE
-       zval *prop;
+       zval *object;
+       zval *property;
+       zval *zptr;
+       void **cache_slot;
        zend_property_info *prop_info;
++      zend_object *zobj;
++      zend_string *name, *tmp_name;
  
        SAVE_OPLINE();
+       object = _get_zval_ptr_cv_BP_VAR_RW(opline->op1.var EXECUTE_DATA_CC);
  
-       if (zend_fetch_static_property_address(&prop, &prop_info, opline->extended_value, BP_VAR_RW, 0 OPLINE_CC EXECUTE_DATA_CC) != SUCCESS) {
-               UNDEF_RESULT();
-               HANDLE_EXCEPTION();
+       if (IS_CV == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+               ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
        }
  
-       zend_pre_incdec_property_zval(prop, prop_info->type ? prop_info : NULL, inc OPLINE_CC EXECUTE_DATA_CC);
+       property = RT_CONSTANT(opline, opline->op2);
+       do {
+               if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+                       if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+                               object = Z_REFVAL_P(object);
+                               goto post_incdec_object;
+                       }
+                       object = make_real_object(object, property OPLINE_CC EXECUTE_DATA_CC);
+                       if (UNEXPECTED(!object)) {
+                               break;
+                       }
+               }
+ post_incdec_object:
+               /* here we are sure we are dealing with an object */
++              zobj = Z_OBJ_P(object);
++              if (IS_CONST == IS_CONST) {
++                      name = Z_STR_P(property);
++              } else {
++                      name = zval_get_tmp_string(property, &tmp_name);
++              }
+               cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL;
 -              if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, cache_slot)) != NULL)) {
++              if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
+                       if (UNEXPECTED(Z_ISERROR_P(zptr))) {
+                               ZVAL_NULL(EX_VAR(opline->result.var));
+                       } else {
+                               if (IS_CONST == IS_CONST) {
+                                       prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
+                               } else {
+                                       prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), zptr);
+                               }
+                               zend_post_incdec_property_zval(zptr, prop_info, inc OPLINE_CC EXECUTE_DATA_CC);
+                       }
+               } else {
 -                      zend_post_incdec_overloaded_property(object, property, cache_slot, inc OPLINE_CC EXECUTE_DATA_CC);
++                      zend_post_incdec_overloaded_property(zobj, name, cache_slot, inc OPLINE_CC EXECUTE_DATA_CC);
++              }
++              if (IS_CONST != IS_CONST) {
++                      zend_tmp_string_release(tmp_name);
+               }
+       } while (0);
  
        ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
  }
@@@ -45154,127 -42459,132 +43309,145 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS
  {
        USE_OPLINE
  
-       zval *prop, *value;
-       zend_property_info *prop_info;
+       zval *object, *property, *value, tmp;
++      zend_object *zobj;
++      zend_string *name, *tmp_name;
  
        SAVE_OPLINE();
+       object = EX_VAR(opline->op1.var);
  
-       if (zend_fetch_static_property_address(&prop, &prop_info, opline->extended_value, BP_VAR_W, 0 OPLINE_CC EXECUTE_DATA_CC) != SUCCESS) {
-               UNDEF_RESULT();
-               HANDLE_EXCEPTION();
-       }
-       value = RT_CONSTANT((opline+1), (opline+1)->op1);
-       if (UNEXPECTED(prop_info->type)) {
-               value = zend_assign_to_typed_prop(prop_info, prop, value EXECUTE_DATA_CC);
-       } else {
-               value = zend_assign_to_variable(prop, value, IS_CONST, EX_USES_STRICT_TYPES());
-       }
-       if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-               ZVAL_COPY(EX_VAR(opline->result.var), value);
+       if (IS_CV == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+               ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
        }
  
-       /* assign_static_prop has two opcodes! */
-       ZEND_VM_NEXT_OPCODE_EX(1, 2);
- }
- static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_STATIC_PROP_SPEC_CV_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
- {
-       USE_OPLINE
-       zend_free_op free_op_data;
-       zval *prop, *value;
-       zend_property_info *prop_info;
+       property = RT_CONSTANT(opline, opline->op2);
+       value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC);
  
-       SAVE_OPLINE();
+       if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+               if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+                       object = Z_REFVAL_P(object);
+                       goto assign_object;
+               }
+               object = make_real_object(object, property OPLINE_CC EXECUTE_DATA_CC);
+               if (UNEXPECTED(!object)) {
  
-       if (zend_fetch_static_property_address(&prop, &prop_info, opline->extended_value, BP_VAR_W, 0 OPLINE_CC EXECUTE_DATA_CC) != SUCCESS) {
-               zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-               UNDEF_RESULT();
-               HANDLE_EXCEPTION();
+                       goto exit_assign_obj;
+               }
        }
  
-       value = _get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC);
+ assign_object:
++      zobj = Z_OBJ_P(object);
+       if (IS_CONST == IS_CONST &&
 -          EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) {
++          EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
+               void **cache_slot = CACHE_ADDR(opline->extended_value);
+               uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+               zend_object *zobj = Z_OBJ_P(object);
+               zval *property_val;
  
-       if (UNEXPECTED(prop_info->type)) {
-               value = zend_assign_to_typed_prop(prop_info, prop, value EXECUTE_DATA_CC);
-               zval_ptr_dtor_nogc(free_op_data);
-       } else {
-               value = zend_assign_to_variable(prop, value, IS_TMP_VAR, EX_USES_STRICT_TYPES());
-       }
+               if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+                       property_val = OBJ_PROP(zobj, prop_offset);
+                       if (Z_TYPE_P(property_val) != IS_UNDEF) {
+                               zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
  
-       if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-               ZVAL_COPY(EX_VAR(opline->result.var), value);
-       }
+                               if (UNEXPECTED(prop_info != NULL)) {
+                                       zend_uchar orig_type = IS_UNDEF;
  
-       /* assign_static_prop has two opcodes! */
-       ZEND_VM_NEXT_OPCODE_EX(1, 2);
- }
+                                       if (IS_CV == IS_CONST) {
+                                               orig_type = Z_TYPE_P(value);
                                      }
  
- static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_STATIC_PROP_SPEC_CV_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
- {
-       USE_OPLINE
-       zend_free_op free_op_data;
-       zval *prop, *value;
-       zend_property_info *prop_info;
+                                       value = zend_assign_to_typed_prop(prop_info, property_val, value EXECUTE_DATA_CC);
  
-       SAVE_OPLINE();
+                                       /* will remain valid, thus no need to check prop_info in future here */
+                                       if (IS_CV == IS_CONST && Z_TYPE_P(value) == orig_type) {
+                                               CACHE_PTR_EX(cache_slot + 2, NULL);
+                                       }
  
-       if (zend_fetch_static_property_address(&prop, &prop_info, opline->extended_value, BP_VAR_W, 0 OPLINE_CC EXECUTE_DATA_CC) != SUCCESS) {
-               zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-               UNDEF_RESULT();
-               HANDLE_EXCEPTION();
-       }
+                               } else {
+ fast_assign_obj:
+                                       value = zend_assign_to_variable(property_val, value, IS_CV, EX_USES_STRICT_TYPES());
+                               }
+                               if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+                                       ZVAL_COPY(EX_VAR(opline->result.var), value);
+                               }
+                               goto exit_assign_obj;
+                       }
+               } else {
+                       if (EXPECTED(zobj->properties != NULL)) {
+                               if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
+                                       if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
+                                               GC_DELREF(zobj->properties);
+                                       }
+                                       zobj->properties = zend_array_dup(zobj->properties);
+                               }
+                               property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1);
+                               if (property_val) {
+                                       goto fast_assign_obj;
+                               }
+                       }
  
-       value = _get_zval_ptr_var((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC);
+                       if (!zobj->ce->__set) {
  
-       if (UNEXPECTED(prop_info->type)) {
-               value = zend_assign_to_typed_prop(prop_info, prop, value EXECUTE_DATA_CC);
-               zval_ptr_dtor_nogc(free_op_data);
-       } else {
-               value = zend_assign_to_variable(prop, value, IS_VAR, EX_USES_STRICT_TYPES());
+                               if (EXPECTED(zobj->properties == NULL)) {
+                                       rebuild_object_properties(zobj);
+                               }
+                               if (IS_CV == IS_CONST) {
+                                       if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
+                                               Z_ADDREF_P(value);
+                                       }
+                               } else if (IS_CV != IS_TMP_VAR) {
+                                       if (Z_ISREF_P(value)) {
+                                               if (IS_CV == IS_VAR) {
+                                                       zend_reference *ref = Z_REF_P(value);
+                                                       if (GC_DELREF(ref) == 0) {
+                                                               ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
+                                                               efree_size(ref, sizeof(zend_reference));
+                                                               value = &tmp;
+                                                       } else {
+                                                               value = Z_REFVAL_P(value);
+                                                               Z_TRY_ADDREF_P(value);
+                                                       }
+                                               } else {
+                                                       value = Z_REFVAL_P(value);
+                                                       Z_TRY_ADDREF_P(value);
+                                               }
+                                       } else if (IS_CV == IS_CV) {
+                                               Z_TRY_ADDREF_P(value);
+                                       }
+                               }
+                               zend_hash_add_new(zobj->properties, Z_STR_P(property), value);
+                               if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+                                       ZVAL_COPY(EX_VAR(opline->result.var), value);
+                               }
+                               goto exit_assign_obj;
+                       }
+               }
        }
  
-       if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-               ZVAL_COPY(EX_VAR(opline->result.var), value);
+       if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+               ZVAL_DEREF(value);
        }
  
-       /* assign_static_prop has two opcodes! */
-       ZEND_VM_NEXT_OPCODE_EX(1, 2);
- }
- static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_STATIC_PROP_SPEC_CV_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
- {
-       USE_OPLINE
-       zval *prop, *value;
-       zend_property_info *prop_info;
-       SAVE_OPLINE();
-       if (zend_fetch_static_property_address(&prop, &prop_info, opline->extended_value, BP_VAR_W, 0 OPLINE_CC EXECUTE_DATA_CC) != SUCCESS) {
-               UNDEF_RESULT();
-               HANDLE_EXCEPTION();
 -      property = Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
++      if (IS_CONST == IS_CONST) {
++              name = Z_STR_P(property);
++      } else {
++              name = zval_get_tmp_string(property, &tmp_name);
 +      }
 +
-       value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC);
-       if (UNEXPECTED(prop_info->type)) {
-               value = zend_assign_to_typed_prop(prop_info, prop, value EXECUTE_DATA_CC);
++      property = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
-       } else {
-               value = zend_assign_to_variable(prop, value, IS_CV, EX_USES_STRICT_TYPES());
++      if (IS_CONST != IS_CONST) {
++              zend_tmp_string_release(tmp_name);
 +      }
  
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-               ZVAL_COPY(EX_VAR(opline->result.var), value);
+               ZVAL_COPY(EX_VAR(opline->result.var), property);
        }
  
-       /* assign_static_prop has two opcodes! */
+ exit_assign_obj:
+       /* assign_obj has two opcodes! */
        ZEND_VM_NEXT_OPCODE_EX(1, 2);
  }