Skip to content

Commit a2e1f6f

Browse files
committed
Stop checking if implements Countable interface in ZPP due to FFI handler
1 parent 67a4b12 commit a2e1f6f

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
@@ -8372,21 +8372,21 @@ ZEND_VM_COLD_CONST_HANDLER(190, ZEND_COUNT, CONST|TMPVAR|CV, UNUSED)
83728372
count = zend_array_count(Z_ARRVAL_P(op1));
83738373
} else if (Z_TYPE_P(op1) == IS_OBJECT) {
83748374
zend_object *zobj = Z_OBJ_P(op1);
8375-
/* if the object implements Countable we call its count() method */
8376-
if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
8377-
zval retval;
8378-
8379-
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
8380-
count = zval_get_long(&retval);
8381-
zval_ptr_dtor(&retval);
8382-
/* Else if the object has a count handler defined */
8383-
} else if (zobj->handlers->count_elements) {
8375+
/* First, check if the handler is defined as it is faster */
8376+
if (zobj->handlers->count_elements) {
83848377
if (FAILURE == zobj->handlers->count_elements(zobj, &count)) {
83858378
zend_type_error("Parameter must be an array or an object that implements Countable");
83868379
}
83878380
if (UNEXPECTED(EG(exception))) {
83888381
count = 0;
83898382
}
8383+
/* Otherwise check if the object implements Countable and call its count() method */
8384+
} else if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
8385+
zval retval;
8386+
8387+
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
8388+
count = zval_get_long(&retval);
8389+
zval_ptr_dtor(&retval);
83908390
} else {
83918391
zend_type_error("Parameter must be an array or an object that implements Countable");
83928392
}

Zend/zend_vm_execute.h

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9214,21 +9214,21 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_CONST_
92149214
count = zend_array_count(Z_ARRVAL_P(op1));
92159215
} else if (Z_TYPE_P(op1) == IS_OBJECT) {
92169216
zend_object *zobj = Z_OBJ_P(op1);
9217-
/* if the object implements Countable we call its count() method */
9218-
if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
9219-
zval retval;
9220-
9221-
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
9222-
count = zval_get_long(&retval);
9223-
zval_ptr_dtor(&retval);
9224-
/* Else if the object has a count handler defined */
9225-
} else if (zobj->handlers->count_elements) {
9217+
/* First, check if the handler is defined as it is faster */
9218+
if (zobj->handlers->count_elements) {
92269219
if (FAILURE == zobj->handlers->count_elements(zobj, &count)) {
92279220
zend_type_error("Parameter must be an array or an object that implements Countable");
92289221
}
92299222
if (UNEXPECTED(EG(exception))) {
92309223
count = 0;
92319224
}
9225+
/* Otherwise check if the object implements Countable and call its count() method */
9226+
} else if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
9227+
zval retval;
9228+
9229+
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
9230+
count = zval_get_long(&retval);
9231+
zval_ptr_dtor(&retval);
92329232
} else {
92339233
zend_type_error("Parameter must be an array or an object that implements Countable");
92349234
}
@@ -16229,21 +16229,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_TMPVAR_UNUSED_HANDL
1622916229
count = zend_array_count(Z_ARRVAL_P(op1));
1623016230
} else if (Z_TYPE_P(op1) == IS_OBJECT) {
1623116231
zend_object *zobj = Z_OBJ_P(op1);
16232-
/* if the object implements Countable we call its count() method */
16233-
if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
16234-
zval retval;
16235-
16236-
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
16237-
count = zval_get_long(&retval);
16238-
zval_ptr_dtor(&retval);
16239-
/* Else if the object has a count handler defined */
16240-
} else if (zobj->handlers->count_elements) {
16232+
/* First, check if the handler is defined as it is faster */
16233+
if (zobj->handlers->count_elements) {
1624116234
if (FAILURE == zobj->handlers->count_elements(zobj, &count)) {
1624216235
zend_type_error("Parameter must be an array or an object that implements Countable");
1624316236
}
1624416237
if (UNEXPECTED(EG(exception))) {
1624516238
count = 0;
1624616239
}
16240+
/* Otherwise check if the object implements Countable and call its count() method */
16241+
} else if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
16242+
zval retval;
16243+
16244+
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
16245+
count = zval_get_long(&retval);
16246+
zval_ptr_dtor(&retval);
1624716247
} else {
1624816248
zend_type_error("Parameter must be an array or an object that implements Countable");
1624916249
}
@@ -44742,21 +44742,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_CV_UNUSED_HANDLER(Z
4474244742
count = zend_array_count(Z_ARRVAL_P(op1));
4474344743
} else if (Z_TYPE_P(op1) == IS_OBJECT) {
4474444744
zend_object *zobj = Z_OBJ_P(op1);
44745-
/* if the object implements Countable we call its count() method */
44746-
if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
44747-
zval retval;
44748-
44749-
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
44750-
count = zval_get_long(&retval);
44751-
zval_ptr_dtor(&retval);
44752-
/* Else if the object has a count handler defined */
44753-
} else if (zobj->handlers->count_elements) {
44745+
/* First, check if the handler is defined as it is faster */
44746+
if (zobj->handlers->count_elements) {
4475444747
if (FAILURE == zobj->handlers->count_elements(zobj, &count)) {
4475544748
zend_type_error("Parameter must be an array or an object that implements Countable");
4475644749
}
4475744750
if (UNEXPECTED(EG(exception))) {
4475844751
count = 0;
4475944752
}
44753+
/* Otherwise check if the object implements Countable and call its count() method */
44754+
} else if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
44755+
zval retval;
44756+
44757+
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
44758+
count = zval_get_long(&retval);
44759+
zval_ptr_dtor(&retval);
4476044760
} else {
4476144761
zend_type_error("Parameter must be an array or an object that implements Countable");
4476244762
}

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)