]> granicus.if.org Git - php/commitdiff
Merge branch 'PHP-7.4'
authorDmitry Stogov <dmitry@zend.com>
Wed, 24 Jul 2019 17:00:55 +0000 (20:00 +0300)
committerDmitry Stogov <dmitry@zend.com>
Wed, 24 Jul 2019 17:00:55 +0000 (20:00 +0300)
* PHP-7.4:
  Avoid over-specialization

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

index 5839ca0f3829e292532f93b62455b4a5035a2c98,930e1cc746e257779651798da3db300ec0a66c32..d1c2b886a45717b06361c42118a2b24d52fe7885
@@@ -8571,9 -8585,10 +8571,9 @@@ ZEND_VM_COLD_CONSTCONST_HANDLER(189, ZE
        ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
  }
  
- ZEND_VM_COLD_CONST_HANDLER(190, ZEND_COUNT, CONST|TMP|VAR|CV, UNUSED)
+ ZEND_VM_COLD_CONST_HANDLER(190, ZEND_COUNT, CONST|TMPVAR|CV, UNUSED)
  {
        USE_OPLINE
 -      zend_free_op free_op1;
        zval *op1;
        zend_long count;
  
index 20fc5450c4b08e5861bea23f849b7add7aaa3622,6dfa6f2899a549d058245943e136383c68a15fe1..8cbd2011c26980bda6ec9c3ba83ec042b26379ae
@@@ -16626,6 -16740,99 +16642,99 @@@ try_instanceof
        ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
  }
  
 -      zend_free_op free_op1;
+ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+ {
+       USE_OPLINE
 -      op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
+       zval *op1;
+       zend_long count;
+       SAVE_OPLINE();
 -                      if (Z_OBJ_HT_P(op1)->count_elements) {
 -                              if (SUCCESS == Z_OBJ_HT_P(op1)->count_elements(op1, &count)) {
++      op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+       while (1) {
+               if (Z_TYPE_P(op1) == IS_ARRAY) {
+                       count = zend_array_count(Z_ARRVAL_P(op1));
+                       break;
+               } else if (Z_TYPE_P(op1) == IS_OBJECT) {
++                      zend_object *zobj = Z_OBJ_P(op1);
++
+                       /* first, we check if the handler is defined */
 -                      if (instanceof_function(Z_OBJCE_P(op1), zend_ce_countable)) {
++                      if (zobj->handlers->count_elements) {
++                              if (SUCCESS == zobj->handlers->count_elements(zobj, &count)) {
+                                       break;
+                               }
+                       }
+                       /* if not and the object implements Countable we call its count() method */
 -                              zend_call_method_with_0_params(op1, NULL, NULL, "count", &retval);
++                      if (instanceof_function(zobj->ce, zend_ce_countable)) {
+                               zval retval;
 -      zval_ptr_dtor_nogc(free_op1);
++                              zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
+                               count = zval_get_long(&retval);
+                               zval_ptr_dtor(&retval);
+                               break;
+                       }
+                       /* If There's no handler and it doesn't implement Countable then add a warning */
+                       count = 1;
+               } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) {
+                       op1 = Z_REFVAL_P(op1);
+                       continue;
+               } else if (Z_TYPE_P(op1) <= IS_NULL) {
+                       if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+                               ZVAL_UNDEFINED_OP1();
+                       }
+                       count = 0;
+               } else {
+                       count = 1;
+               }
+               zend_error(E_WARNING, "%s(): Parameter must be an array or an object that implements Countable", opline->extended_value ? "sizeof" : "count");
+               break;
+       }
+       ZVAL_LONG(EX_VAR(opline->result.var), count);
 -              zend_free_op free_op1;
++      zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+       ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ }
+ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+ {
+       USE_OPLINE
+       if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
+               if (UNEXPECTED(!EX(func)->common.scope)) {
+                       SAVE_OPLINE();
+                       zend_error(E_WARNING, "get_class() called without object from outside a class");
+                       ZVAL_FALSE(EX_VAR(opline->result.var));
+                       ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+               } else {
+                       ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(func)->common.scope->name);
+                       ZEND_VM_NEXT_OPCODE();
+               }
+       } else {
 -              op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
+               zval *op1;
+               SAVE_OPLINE();
 -              zval_ptr_dtor_nogc(free_op1);
++              op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+               while (1) {
+                       if (Z_TYPE_P(op1) == IS_OBJECT) {
+                               ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op1)->name);
+                       } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) {
+                               op1 = Z_REFVAL_P(op1);
+                               continue;
+                       } else {
+                               if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+                                       ZVAL_UNDEFINED_OP1();
+                               }
+                               zend_error(E_WARNING, "get_class() expects parameter 1 to be object, %s given", zend_get_type_by_const(Z_TYPE_P(op1)));
+                               ZVAL_FALSE(EX_VAR(opline->result.var));
+                       }
+                       break;
+               }
++              zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+               ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+       }
+ }
  static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
  {
        USE_OPLINE