@@ -886,6 +886,28 @@ static const func_info_t func_infos[] = {
886886static HashTable func_info ;
887887int zend_func_info_rid = -1 ;
888888
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+
889911uint32_t zend_get_func_info (
890912 const zend_call_info * call_info , const zend_ssa * ssa ,
891913 zend_class_entry * * ce , zend_bool * ce_is_instanceof )
@@ -896,21 +918,14 @@ uint32_t zend_get_func_info(
896918 * ce_is_instanceof = 0 ;
897919
898920 if (callee_func -> type == ZEND_INTERNAL_FUNCTION ) {
899- zval * zv ;
900921 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 ));
901922
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 ;
913927 }
928+ #endif
914929
915930 if (callee_func -> common .fn_flags & ZEND_ACC_HAS_RETURN_TYPE ) {
916931 ret = zend_fetch_arg_info_type (NULL , callee_func -> common .arg_info - 1 , ce );
@@ -925,6 +940,17 @@ uint32_t zend_get_func_info(
925940 if (callee_func -> common .fn_flags & ZEND_ACC_RETURN_REFERENCE ) {
926941 ret |= MAY_BE_REF ;
927942 }
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
928954 } else {
929955 // FIXME: the order of functions matters!!!
930956 zend_func_info * info = ZEND_FUNC_INFO ((zend_op_array * )callee_func );
0 commit comments