Skip to content

Commit 55f22b7

Browse files
committed
Stop checking if implements Countable interface in ZPP due to FFI handler
1 parent 8fcf0ee commit 55f22b7

File tree

3 files changed

+46
-43
lines changed

3 files changed

+46
-43
lines changed

Zend/zend_vm_def.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8436,21 +8436,21 @@ ZEND_VM_COLD_CONST_HANDLER(190, ZEND_COUNT, CONST|TMPVAR|CV, UNUSED)
84368436
count = zend_array_count(Z_ARRVAL_P(op1));
84378437
} else if (Z_TYPE_P(op1) == IS_OBJECT) {
84388438
zend_object *zobj = Z_OBJ_P(op1);
8439-
/* if the object implements Countable we call its count() method */
8440-
if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
8441-
zval retval;
8442-
8443-
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
8444-
count = zval_get_long(&retval);
8445-
zval_ptr_dtor(&retval);
8446-
/* Else if the object has a count handler defined */
8447-
} else if (zobj->handlers->count_elements) {
8439+
/* First, check if the handler is defined as it is faster */
8440+
if (zobj->handlers->count_elements) {
84488441
if (FAILURE == zobj->handlers->count_elements(zobj, &count)) {
84498442
zend_type_error("Parameter must be an array or an object that implements Countable");
84508443
}
84518444
if (UNEXPECTED(EG(exception))) {
84528445
count = 0;
84538446
}
8447+
/* Otherwise check if the object implements Countable and call its count() method */
8448+
} else if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
8449+
zval retval;
8450+
8451+
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
8452+
count = zval_get_long(&retval);
8453+
zval_ptr_dtor(&retval);
84548454
} else {
84558455
zend_type_error("Parameter must be an array or an object that implements Countable");
84568456
}

Zend/zend_vm_execute.h

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9270,21 +9270,21 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_CONST_
92709270
count = zend_array_count(Z_ARRVAL_P(op1));
92719271
} else if (Z_TYPE_P(op1) == IS_OBJECT) {
92729272
zend_object *zobj = Z_OBJ_P(op1);
9273-
/* if the object implements Countable we call its count() method */
9274-
if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
9275-
zval retval;
9276-
9277-
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
9278-
count = zval_get_long(&retval);
9279-
zval_ptr_dtor(&retval);
9280-
/* Else if the object has a count handler defined */
9281-
} else if (zobj->handlers->count_elements) {
9273+
/* First, check if the handler is defined as it is faster */
9274+
if (zobj->handlers->count_elements) {
92829275
if (FAILURE == zobj->handlers->count_elements(zobj, &count)) {
92839276
zend_type_error("Parameter must be an array or an object that implements Countable");
92849277
}
92859278
if (UNEXPECTED(EG(exception))) {
92869279
count = 0;
92879280
}
9281+
/* Otherwise check if the object implements Countable and call its count() method */
9282+
} else if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
9283+
zval retval;
9284+
9285+
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
9286+
count = zval_get_long(&retval);
9287+
zval_ptr_dtor(&retval);
92889288
} else {
92899289
zend_type_error("Parameter must be an array or an object that implements Countable");
92909290
}
@@ -16279,21 +16279,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_TMPVAR_UNUSED_HANDL
1627916279
count = zend_array_count(Z_ARRVAL_P(op1));
1628016280
} else if (Z_TYPE_P(op1) == IS_OBJECT) {
1628116281
zend_object *zobj = Z_OBJ_P(op1);
16282-
/* if the object implements Countable we call its count() method */
16283-
if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
16284-
zval retval;
16285-
16286-
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
16287-
count = zval_get_long(&retval);
16288-
zval_ptr_dtor(&retval);
16289-
/* Else if the object has a count handler defined */
16290-
} else if (zobj->handlers->count_elements) {
16282+
/* First, check if the handler is defined as it is faster */
16283+
if (zobj->handlers->count_elements) {
1629116284
if (FAILURE == zobj->handlers->count_elements(zobj, &count)) {
1629216285
zend_type_error("Parameter must be an array or an object that implements Countable");
1629316286
}
1629416287
if (UNEXPECTED(EG(exception))) {
1629516288
count = 0;
1629616289
}
16290+
/* Otherwise check if the object implements Countable and call its count() method */
16291+
} else if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
16292+
zval retval;
16293+
16294+
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
16295+
count = zval_get_long(&retval);
16296+
zval_ptr_dtor(&retval);
1629716297
} else {
1629816298
zend_type_error("Parameter must be an array or an object that implements Countable");
1629916299
}
@@ -45039,21 +45039,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_CV_UNUSED_HANDLER(Z
4503945039
count = zend_array_count(Z_ARRVAL_P(op1));
4504045040
} else if (Z_TYPE_P(op1) == IS_OBJECT) {
4504145041
zend_object *zobj = Z_OBJ_P(op1);
45042-
/* if the object implements Countable we call its count() method */
45043-
if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
45044-
zval retval;
45045-
45046-
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
45047-
count = zval_get_long(&retval);
45048-
zval_ptr_dtor(&retval);
45049-
/* Else if the object has a count handler defined */
45050-
} else if (zobj->handlers->count_elements) {
45042+
/* First, check if the handler is defined as it is faster */
45043+
if (zobj->handlers->count_elements) {
4505145044
if (FAILURE == zobj->handlers->count_elements(zobj, &count)) {
4505245045
zend_type_error("Parameter must be an array or an object that implements Countable");
4505345046
}
4505445047
if (UNEXPECTED(EG(exception))) {
4505545048
count = 0;
4505645049
}
45050+
/* Otherwise check if the object implements Countable and call its count() method */
45051+
} else if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
45052+
zval retval;
45053+
45054+
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
45055+
count = zval_get_long(&retval);
45056+
zval_ptr_dtor(&retval);
4505745057
} else {
4505845058
zend_type_error("Parameter must be an array or an object that implements Countable");
4505945059
}

ext/standard/array.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -779,14 +779,13 @@ PHP_FUNCTION(count)
779779
}
780780

781781
/* Remove possibility to specify $mode when passing object? */
782-
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "O|l",
783-
&countable, zend_ce_countable, &mode) == SUCCESS) {
782+
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "o|l",
783+
&countable, &mode) == SUCCESS) {
784784
if (mode != COUNT_NORMAL && mode != COUNT_RECURSIVE) {
785785
zend_value_error("Mode value is invalid");
786786
return;
787787
}
788-
zval retval;
789-
/* First, we check if the count handler is defined */
788+
/* First, check if the handler is defined as it is faster */
790789
if (Z_OBJ_HT_P(countable)->count_elements) {
791790
RETVAL_LONG(1);
792791
if (SUCCESS == Z_OBJ_HT(*countable)->count_elements(Z_OBJ_P(countable), &Z_LVAL_P(return_value))) {
@@ -795,14 +794,18 @@ PHP_FUNCTION(count)
795794
if (EG(exception)) {
796795
return;
797796
}
798-
} else {
797+
}
798+
799+
zval retval;
800+
/* Otherwise check if the object implements Countable and call its count() method */
801+
if (instanceof_function(Z_OBJCE_P(countable), zend_ce_countable)) {
799802
zend_call_method_with_0_params(Z_OBJ_P(countable), NULL, NULL, "count", &retval);
800803
if (Z_TYPE(retval) != IS_UNDEF) {
801804
RETVAL_LONG(zval_get_long(&retval));
805+
zval_ptr_dtor(&retval);
802806
}
807+
return;
803808
}
804-
zval_ptr_dtor(&retval);
805-
return;
806809
}
807810
zend_type_error("Parameter must be an array or an object that implements Countable");
808811
return;

0 commit comments

Comments
 (0)