Skip to content

Commit 95b30d9

Browse files
committed
Stop checking if implements Countable interface in ZPP due to FFI handler
1 parent ffc40da commit 95b30d9

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
@@ -8431,21 +8431,21 @@ ZEND_VM_COLD_CONST_HANDLER(190, ZEND_COUNT, CONST|TMPVAR|CV, UNUSED)
84318431
count = zend_array_count(Z_ARRVAL_P(op1));
84328432
} else if (Z_TYPE_P(op1) == IS_OBJECT) {
84338433
zend_object *zobj = Z_OBJ_P(op1);
8434-
/* if the object implements Countable we call its count() method */
8435-
if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
8436-
zval retval;
8437-
8438-
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
8439-
count = zval_get_long(&retval);
8440-
zval_ptr_dtor(&retval);
8441-
/* Else if the object has a count handler defined */
8442-
} else if (zobj->handlers->count_elements) {
8434+
/* First, check if the handler is defined as it is faster */
8435+
if (zobj->handlers->count_elements) {
84438436
if (FAILURE == zobj->handlers->count_elements(zobj, &count)) {
84448437
zend_type_error("Parameter must be an array or an object that implements Countable");
84458438
}
84468439
if (UNEXPECTED(EG(exception))) {
84478440
count = 0;
84488441
}
8442+
/* Otherwise check if the object implements Countable and call its count() method */
8443+
} else if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
8444+
zval retval;
8445+
8446+
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
8447+
count = zval_get_long(&retval);
8448+
zval_ptr_dtor(&retval);
84498449
} else {
84508450
zend_type_error("Parameter must be an array or an object that implements Countable");
84518451
}

Zend/zend_vm_execute.h

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9263,21 +9263,21 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_CONST_
92639263
count = zend_array_count(Z_ARRVAL_P(op1));
92649264
} else if (Z_TYPE_P(op1) == IS_OBJECT) {
92659265
zend_object *zobj = Z_OBJ_P(op1);
9266-
/* if the object implements Countable we call its count() method */
9267-
if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
9268-
zval retval;
9269-
9270-
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
9271-
count = zval_get_long(&retval);
9272-
zval_ptr_dtor(&retval);
9273-
/* Else if the object has a count handler defined */
9274-
} else if (zobj->handlers->count_elements) {
9266+
/* First, check if the handler is defined as it is faster */
9267+
if (zobj->handlers->count_elements) {
92759268
if (FAILURE == zobj->handlers->count_elements(zobj, &count)) {
92769269
zend_type_error("Parameter must be an array or an object that implements Countable");
92779270
}
92789271
if (UNEXPECTED(EG(exception))) {
92799272
count = 0;
92809273
}
9274+
/* Otherwise check if the object implements Countable and call its count() method */
9275+
} else if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
9276+
zval retval;
9277+
9278+
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
9279+
count = zval_get_long(&retval);
9280+
zval_ptr_dtor(&retval);
92819281
} else {
92829282
zend_type_error("Parameter must be an array or an object that implements Countable");
92839283
}
@@ -16278,21 +16278,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_TMPVAR_UNUSED_HANDL
1627816278
count = zend_array_count(Z_ARRVAL_P(op1));
1627916279
} else if (Z_TYPE_P(op1) == IS_OBJECT) {
1628016280
zend_object *zobj = Z_OBJ_P(op1);
16281-
/* if the object implements Countable we call its count() method */
16282-
if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
16283-
zval retval;
16284-
16285-
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
16286-
count = zval_get_long(&retval);
16287-
zval_ptr_dtor(&retval);
16288-
/* Else if the object has a count handler defined */
16289-
} else if (zobj->handlers->count_elements) {
16281+
/* First, check if the handler is defined as it is faster */
16282+
if (zobj->handlers->count_elements) {
1629016283
if (FAILURE == zobj->handlers->count_elements(zobj, &count)) {
1629116284
zend_type_error("Parameter must be an array or an object that implements Countable");
1629216285
}
1629316286
if (UNEXPECTED(EG(exception))) {
1629416287
count = 0;
1629516288
}
16289+
/* Otherwise check if the object implements Countable and call its count() method */
16290+
} else if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
16291+
zval retval;
16292+
16293+
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
16294+
count = zval_get_long(&retval);
16295+
zval_ptr_dtor(&retval);
1629616296
} else {
1629716297
zend_type_error("Parameter must be an array or an object that implements Countable");
1629816298
}
@@ -45068,21 +45068,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_CV_UNUSED_HANDLER(Z
4506845068
count = zend_array_count(Z_ARRVAL_P(op1));
4506945069
} else if (Z_TYPE_P(op1) == IS_OBJECT) {
4507045070
zend_object *zobj = Z_OBJ_P(op1);
45071-
/* if the object implements Countable we call its count() method */
45072-
if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
45073-
zval retval;
45074-
45075-
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
45076-
count = zval_get_long(&retval);
45077-
zval_ptr_dtor(&retval);
45078-
/* Else if the object has a count handler defined */
45079-
} else if (zobj->handlers->count_elements) {
45071+
/* First, check if the handler is defined as it is faster */
45072+
if (zobj->handlers->count_elements) {
4508045073
if (FAILURE == zobj->handlers->count_elements(zobj, &count)) {
4508145074
zend_type_error("Parameter must be an array or an object that implements Countable");
4508245075
}
4508345076
if (UNEXPECTED(EG(exception))) {
4508445077
count = 0;
4508545078
}
45079+
/* Otherwise check if the object implements Countable and call its count() method */
45080+
} else if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
45081+
zval retval;
45082+
45083+
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
45084+
count = zval_get_long(&retval);
45085+
zval_ptr_dtor(&retval);
4508645086
} else {
4508745087
zend_type_error("Parameter must be an array or an object that implements Countable");
4508845088
}

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)