@@ -886,6 +886,28 @@ static const func_info_t func_infos[] = {
886
886
static HashTable func_info ;
887
887
int zend_func_info_rid = -1 ;
888
888
889
+ static uint32_t get_internal_func_info (
890
+ const zend_call_info * call_info , const zend_ssa * ssa , zend_string * lcname ) {
891
+ if (call_info -> callee_func -> common .scope ) {
892
+ /* This is a method, not a function. */
893
+ return 0 ;
894
+ }
895
+
896
+ zval * zv = zend_hash_find_ex (& func_info , lcname , 1 );
897
+ if (!zv ) {
898
+ return 0 ;
899
+ }
900
+
901
+ func_info_t * info = Z_PTR_P (zv );
902
+ if (UNEXPECTED (zend_optimizer_is_disabled_func (info -> name , info -> name_len ))) {
903
+ return MAY_BE_NULL ;
904
+ } else if (info -> info_func ) {
905
+ return info -> info_func (call_info , ssa );
906
+ } else {
907
+ return info -> info ;
908
+ }
909
+ }
910
+
889
911
uint32_t zend_get_func_info (
890
912
const zend_call_info * call_info , const zend_ssa * ssa ,
891
913
zend_class_entry * * ce , zend_bool * ce_is_instanceof )
@@ -896,21 +918,14 @@ uint32_t zend_get_func_info(
896
918
* ce_is_instanceof = 0 ;
897
919
898
920
if (callee_func -> type == ZEND_INTERNAL_FUNCTION ) {
899
- zval * zv ;
900
921
zend_string * lcname = Z_STR_P (CRT_CONSTANT_EX (call_info -> caller_op_array , call_info -> caller_init_opline , call_info -> caller_init_opline -> op2 ));
901
922
902
- if (!call_info -> callee_func -> common .scope
903
- && (zv = zend_hash_find_ex (& func_info , lcname , 1 ))) {
904
- func_info_t * info = Z_PTR_P (zv );
905
- if (UNEXPECTED (zend_optimizer_is_disabled_func (info -> name , info -> name_len ))) {
906
- ret = MAY_BE_NULL ;
907
- } else if (info -> info_func ) {
908
- ret = info -> info_func (call_info , ssa );
909
- } else {
910
- ret = info -> info ;
911
- }
912
- return ret ;
923
+ uint32_t internal_ret = get_internal_func_info (call_info , ssa , lcname );
924
+ #if !ZEND_DEBUG
925
+ if (internal_ret ) {
926
+ return internal_ret ;
913
927
}
928
+ #endif
914
929
915
930
if (callee_func -> common .fn_flags & ZEND_ACC_HAS_RETURN_TYPE ) {
916
931
ret = zend_fetch_arg_info_type (NULL , callee_func -> common .arg_info - 1 , ce );
@@ -925,6 +940,17 @@ uint32_t zend_get_func_info(
925
940
if (callee_func -> common .fn_flags & ZEND_ACC_RETURN_REFERENCE ) {
926
941
ret |= MAY_BE_REF ;
927
942
}
943
+
944
+ #if ZEND_DEBUG
945
+ /* Check whether the func_info information is a subset of the information we can compute
946
+ * from the specified return type. */
947
+ if (internal_ret ) {
948
+ if (internal_ret & ~ret ) {
949
+ fprintf (stderr , "Inaccurate func info for %s()\n" , ZSTR_VAL (lcname ));
950
+ }
951
+ return internal_ret ;
952
+ }
953
+ #endif
928
954
} else {
929
955
// FIXME: the order of functions matters!!!
930
956
zend_func_info * info = ZEND_FUNC_INFO ((zend_op_array * )callee_func );
0 commit comments