Skip to content

Commit 4e0c639

Browse files
committed
Stop checking if implements Countable interface in ZPP due to FFI handler
1 parent 0d10903 commit 4e0c639

File tree

3 files changed

+43
-39
lines changed

3 files changed

+43
-39
lines changed

Zend/zend_vm_def.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8458,21 +8458,21 @@ ZEND_VM_COLD_CONST_HANDLER(190, ZEND_COUNT, CONST|TMPVAR|CV, UNUSED)
84588458
count = zend_array_count(Z_ARRVAL_P(op1));
84598459
} else if (Z_TYPE_P(op1) == IS_OBJECT) {
84608460
zend_object *zobj = Z_OBJ_P(op1);
8461-
/* if the object implements Countable we call its count() method */
8462-
if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
8463-
zval retval;
8464-
8465-
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
8466-
count = zval_get_long(&retval);
8467-
zval_ptr_dtor(&retval);
8468-
/* Else if the object has a count handler defined */
8469-
} else if (zobj->handlers->count_elements) {
8461+
/* First, check if the handler is defined as it is faster */
8462+
if (zobj->handlers->count_elements) {
84708463
if (FAILURE == zobj->handlers->count_elements(zobj, &count)) {
84718464
zend_type_error("Parameter must be an array or an object that implements Countable");
84728465
}
84738466
if (UNEXPECTED(EG(exception))) {
84748467
count = 0;
84758468
}
8469+
/* Otherwise check if the object implements Countable and call its count() method */
8470+
} else if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
8471+
zval retval;
8472+
8473+
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
8474+
count = zval_get_long(&retval);
8475+
zval_ptr_dtor(&retval);
84768476
} else {
84778477
zend_type_error("Parameter must be an array or an object that implements Countable");
84788478
}

Zend/zend_vm_execute.h

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9275,21 +9275,21 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_CONST_
92759275
count = zend_array_count(Z_ARRVAL_P(op1));
92769276
} else if (Z_TYPE_P(op1) == IS_OBJECT) {
92779277
zend_object *zobj = Z_OBJ_P(op1);
9278-
/* if the object implements Countable we call its count() method */
9279-
if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
9280-
zval retval;
9281-
9282-
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
9283-
count = zval_get_long(&retval);
9284-
zval_ptr_dtor(&retval);
9285-
/* Else if the object has a count handler defined */
9286-
} else if (zobj->handlers->count_elements) {
9278+
/* First, check if the handler is defined as it is faster */
9279+
if (zobj->handlers->count_elements) {
92879280
if (FAILURE == zobj->handlers->count_elements(zobj, &count)) {
92889281
zend_type_error("Parameter must be an array or an object that implements Countable");
92899282
}
92909283
if (UNEXPECTED(EG(exception))) {
92919284
count = 0;
92929285
}
9286+
/* Otherwise check if the object implements Countable and call its count() method */
9287+
} else if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
9288+
zval retval;
9289+
9290+
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
9291+
count = zval_get_long(&retval);
9292+
zval_ptr_dtor(&retval);
92939293
} else {
92949294
zend_type_error("Parameter must be an array or an object that implements Countable");
92959295
}
@@ -16347,21 +16347,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_TMPVAR_UNUSED_HANDL
1634716347
count = zend_array_count(Z_ARRVAL_P(op1));
1634816348
} else if (Z_TYPE_P(op1) == IS_OBJECT) {
1634916349
zend_object *zobj = Z_OBJ_P(op1);
16350-
/* if the object implements Countable we call its count() method */
16351-
if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
16352-
zval retval;
16353-
16354-
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
16355-
count = zval_get_long(&retval);
16356-
zval_ptr_dtor(&retval);
16357-
/* Else if the object has a count handler defined */
16358-
} else if (zobj->handlers->count_elements) {
16350+
/* First, check if the handler is defined as it is faster */
16351+
if (zobj->handlers->count_elements) {
1635916352
if (FAILURE == zobj->handlers->count_elements(zobj, &count)) {
1636016353
zend_type_error("Parameter must be an array or an object that implements Countable");
1636116354
}
1636216355
if (UNEXPECTED(EG(exception))) {
1636316356
count = 0;
1636416357
}
16358+
/* Otherwise check if the object implements Countable and call its count() method */
16359+
} else if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
16360+
zval retval;
16361+
16362+
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
16363+
count = zval_get_long(&retval);
16364+
zval_ptr_dtor(&retval);
1636516365
} else {
1636616366
zend_type_error("Parameter must be an array or an object that implements Countable");
1636716367
}
@@ -45187,21 +45187,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_CV_UNUSED_HANDLER(Z
4518745187
count = zend_array_count(Z_ARRVAL_P(op1));
4518845188
} else if (Z_TYPE_P(op1) == IS_OBJECT) {
4518945189
zend_object *zobj = Z_OBJ_P(op1);
45190-
/* if the object implements Countable we call its count() method */
45191-
if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
45192-
zval retval;
45193-
45194-
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
45195-
count = zval_get_long(&retval);
45196-
zval_ptr_dtor(&retval);
45197-
/* Else if the object has a count handler defined */
45198-
} else if (zobj->handlers->count_elements) {
45190+
/* First, check if the handler is defined as it is faster */
45191+
if (zobj->handlers->count_elements) {
4519945192
if (FAILURE == zobj->handlers->count_elements(zobj, &count)) {
4520045193
zend_type_error("Parameter must be an array or an object that implements Countable");
4520145194
}
4520245195
if (UNEXPECTED(EG(exception))) {
4520345196
count = 0;
4520445197
}
45198+
/* Otherwise check if the object implements Countable and call its count() method */
45199+
} else if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
45200+
zval retval;
45201+
45202+
zend_call_method_with_0_params(zobj, NULL, NULL, "count", &retval);
45203+
count = zval_get_long(&retval);
45204+
zval_ptr_dtor(&retval);
4520545205
} else {
4520645206
zend_type_error("Parameter must be an array or an object that implements Countable");
4520745207
}

ext/standard/array.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -735,14 +735,18 @@ PHP_FUNCTION(count)
735735
if (EG(exception)) {
736736
return;
737737
}
738-
} else {
738+
}
739+
740+
zval retval;
741+
/* Otherwise check if the object implements Countable and call its count() method */
742+
if (instanceof_function(Z_OBJCE_P(countable), zend_ce_countable)) {
739743
zend_call_method_with_0_params(Z_OBJ_P(countable), NULL, NULL, "count", &retval);
740744
if (Z_TYPE(retval) != IS_UNDEF) {
741745
RETVAL_LONG(zval_get_long(&retval));
746+
zval_ptr_dtor(&retval);
742747
}
748+
return;
743749
}
744-
zval_ptr_dtor(&retval);
745-
return;
746750
}
747751
zend_type_error("Parameter must be an array or an object that implements Countable");
748752
return;

0 commit comments

Comments
 (0)