Skip to content

Commit 51199e2

Browse files
committed
Stop checking if implements Countable interface in ZPP due to FFI handler
1 parent 0e259a6 commit 51199e2

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
@@ -8389,21 +8389,21 @@ ZEND_VM_COLD_CONST_HANDLER(190, ZEND_COUNT, CONST|TMPVAR|CV, UNUSED)
83898389
count = zend_array_count(Z_ARRVAL_P(op1));
83908390
} else if (Z_TYPE_P(op1) == IS_OBJECT) {
83918391
zend_object *zobj = Z_OBJ_P(op1);
8392-
/* if the object implements Countable we call its count() method */
8393-
if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
8394-
zval retval;
8395-
8396-
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
8397-
count = zval_get_long(&retval);
8398-
zval_ptr_dtor(&retval);
8399-
/* Else if the object has a count handler defined */
8400-
} else if (zobj->handlers->count_elements) {
8392+
/* First, check if the handler is defined as it is faster */
8393+
if (zobj->handlers->count_elements) {
84018394
if (FAILURE == zobj->handlers->count_elements(zobj, &count)) {
84028395
zend_type_error("Parameter must be an array or an object that implements Countable");
84038396
}
84048397
if (UNEXPECTED(EG(exception))) {
84058398
count = 0;
84068399
}
8400+
/* Otherwise check if the object implements Countable and call its count() method */
8401+
} else if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
8402+
zval retval;
8403+
8404+
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
8405+
count = zval_get_long(&retval);
8406+
zval_ptr_dtor(&retval);
84078407
} else {
84088408
zend_type_error("Parameter must be an array or an object that implements Countable");
84098409
}

Zend/zend_vm_execute.h

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9231,21 +9231,21 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_CONST_
92319231
count = zend_array_count(Z_ARRVAL_P(op1));
92329232
} else if (Z_TYPE_P(op1) == IS_OBJECT) {
92339233
zend_object *zobj = Z_OBJ_P(op1);
9234-
/* if the object implements Countable we call its count() method */
9235-
if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
9236-
zval retval;
9237-
9238-
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
9239-
count = zval_get_long(&retval);
9240-
zval_ptr_dtor(&retval);
9241-
/* Else if the object has a count handler defined */
9242-
} else if (zobj->handlers->count_elements) {
9234+
/* First, check if the handler is defined as it is faster */
9235+
if (zobj->handlers->count_elements) {
92439236
if (FAILURE == zobj->handlers->count_elements(zobj, &count)) {
92449237
zend_type_error("Parameter must be an array or an object that implements Countable");
92459238
}
92469239
if (UNEXPECTED(EG(exception))) {
92479240
count = 0;
92489241
}
9242+
/* Otherwise check if the object implements Countable and call its count() method */
9243+
} else if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
9244+
zval retval;
9245+
9246+
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
9247+
count = zval_get_long(&retval);
9248+
zval_ptr_dtor(&retval);
92499249
} else {
92509250
zend_type_error("Parameter must be an array or an object that implements Countable");
92519251
}
@@ -16246,21 +16246,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_TMPVAR_UNUSED_HANDL
1624616246
count = zend_array_count(Z_ARRVAL_P(op1));
1624716247
} else if (Z_TYPE_P(op1) == IS_OBJECT) {
1624816248
zend_object *zobj = Z_OBJ_P(op1);
16249-
/* if the object implements Countable we call its count() method */
16250-
if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
16251-
zval retval;
16252-
16253-
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
16254-
count = zval_get_long(&retval);
16255-
zval_ptr_dtor(&retval);
16256-
/* Else if the object has a count handler defined */
16257-
} else if (zobj->handlers->count_elements) {
16249+
/* First, check if the handler is defined as it is faster */
16250+
if (zobj->handlers->count_elements) {
1625816251
if (FAILURE == zobj->handlers->count_elements(zobj, &count)) {
1625916252
zend_type_error("Parameter must be an array or an object that implements Countable");
1626016253
}
1626116254
if (UNEXPECTED(EG(exception))) {
1626216255
count = 0;
1626316256
}
16257+
/* Otherwise check if the object implements Countable and call its count() method */
16258+
} else if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
16259+
zval retval;
16260+
16261+
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
16262+
count = zval_get_long(&retval);
16263+
zval_ptr_dtor(&retval);
1626416264
} else {
1626516265
zend_type_error("Parameter must be an array or an object that implements Countable");
1626616266
}
@@ -44803,21 +44803,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_CV_UNUSED_HANDLER(Z
4480344803
count = zend_array_count(Z_ARRVAL_P(op1));
4480444804
} else if (Z_TYPE_P(op1) == IS_OBJECT) {
4480544805
zend_object *zobj = Z_OBJ_P(op1);
44806-
/* if the object implements Countable we call its count() method */
44807-
if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
44808-
zval retval;
44809-
44810-
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
44811-
count = zval_get_long(&retval);
44812-
zval_ptr_dtor(&retval);
44813-
/* Else if the object has a count handler defined */
44814-
} else if (zobj->handlers->count_elements) {
44806+
/* First, check if the handler is defined as it is faster */
44807+
if (zobj->handlers->count_elements) {
4481544808
if (FAILURE == zobj->handlers->count_elements(zobj, &count)) {
4481644809
zend_type_error("Parameter must be an array or an object that implements Countable");
4481744810
}
4481844811
if (UNEXPECTED(EG(exception))) {
4481944812
count = 0;
4482044813
}
44814+
/* Otherwise check if the object implements Countable and call its count() method */
44815+
} else if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
44816+
zval retval;
44817+
44818+
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
44819+
count = zval_get_long(&retval);
44820+
zval_ptr_dtor(&retval);
4482144821
} else {
4482244822
zend_type_error("Parameter must be an array or an object that implements Countable");
4482344823
}

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)