@@ -104,9 +104,7 @@ zend_result zend_optimizer_eval_special_func_call(
104104 zval * result , const zend_string * name , zend_string * arg ) {
105105 if (zend_string_equals_literal (name , "function_exists" ) ||
106106 zend_string_equals_literal (name , "is_callable" )) {
107- zend_string * lc_name = zend_string_tolower (arg );
108- const zend_internal_function * func = zend_hash_find_ptr (EG (function_table ), lc_name );
109- zend_string_release_ex (lc_name , 0 );
107+ const zend_internal_function * func = zend_hash_find_ptr (EG (function_table ), arg );
110108
111109 if (func && func -> type == ZEND_INTERNAL_FUNCTION
112110 && func -> module -> type == MODULE_PERSISTENT
@@ -290,7 +288,8 @@ bool zend_optimizer_update_op1_const(zend_op_array *op_array,
290288 drop_leading_backslash (val );
291289 opline -> op1 .constant = zend_optimizer_add_literal (op_array , val );
292290 opline -> extended_value = alloc_cache_slots (op_array , 1 ) | (opline -> extended_value & ZEND_LAST_CATCH );
293- zend_optimizer_add_literal_string (op_array , zend_string_tolower (Z_STR_P (val )));
291+ zend_string_addref (Z_STR_P (val ));
292+ zend_optimizer_add_literal_string (op_array , Z_STR_P (val ));
294293 break ;
295294 case ZEND_DEFINED :
296295 REQUIRES_STRING (val );
@@ -304,7 +303,8 @@ bool zend_optimizer_update_op1_const(zend_op_array *op_array,
304303 drop_leading_backslash (val );
305304 opline -> op1 .constant = zend_optimizer_add_literal (op_array , val );
306305 opline -> op2 .num = alloc_cache_slots (op_array , 1 );
307- zend_optimizer_add_literal_string (op_array , zend_string_tolower (Z_STR_P (val )));
306+ zend_string_addref (Z_STR_P (val ));
307+ zend_optimizer_add_literal_string (op_array , Z_STR_P (val ));
308308 break ;
309309 case ZEND_INIT_STATIC_METHOD_CALL :
310310 REQUIRES_STRING (val );
@@ -313,7 +313,8 @@ bool zend_optimizer_update_op1_const(zend_op_array *op_array,
313313 if (opline -> op2_type != IS_CONST ) {
314314 opline -> result .num = alloc_cache_slots (op_array , 1 );
315315 }
316- zend_optimizer_add_literal_string (op_array , zend_string_tolower (Z_STR_P (val )));
316+ zend_string_addref (Z_STR_P (val ));
317+ zend_optimizer_add_literal_string (op_array , Z_STR_P (val ));
317318 break ;
318319 case ZEND_FETCH_CLASS_CONSTANT :
319320 REQUIRES_STRING (val );
@@ -322,7 +323,8 @@ bool zend_optimizer_update_op1_const(zend_op_array *op_array,
322323 if (opline -> op2_type != IS_CONST ) {
323324 opline -> extended_value = alloc_cache_slots (op_array , 1 );
324325 }
325- zend_optimizer_add_literal_string (op_array , zend_string_tolower (Z_STR_P (val )));
326+ zend_string_addref (Z_STR_P (val ));
327+ zend_optimizer_add_literal_string (op_array , Z_STR_P (val ));
326328 break ;
327329 case ZEND_ASSIGN_OP :
328330 case ZEND_ASSIGN_DIM_OP :
@@ -428,14 +430,14 @@ bool zend_optimizer_update_op2_const(zend_op_array *op_array,
428430 REQUIRES_STRING (val );
429431 drop_leading_backslash (val );
430432 opline -> op2 .constant = zend_optimizer_add_literal (op_array , val );
431- zend_optimizer_add_literal_string (op_array , zend_string_tolower (Z_STR_P (val )));
433+ zend_string_addref (Z_STR_P (val ));
434+ zend_optimizer_add_literal_string (op_array , Z_STR_P (val ));
432435 opline -> extended_value = alloc_cache_slots (op_array , 1 );
433436 break ;
434437 case ZEND_INIT_FCALL_BY_NAME :
435438 REQUIRES_STRING (val );
436439 drop_leading_backslash (val );
437440 opline -> op2 .constant = zend_optimizer_add_literal (op_array , val );
438- zend_optimizer_add_literal_string (op_array , zend_string_tolower (Z_STR_P (val )));
439441 opline -> result .num = alloc_cache_slots (op_array , 1 );
440442 break ;
441443 case ZEND_ASSIGN_STATIC_PROP :
@@ -456,20 +458,14 @@ bool zend_optimizer_update_op2_const(zend_op_array *op_array,
456458 REQUIRES_STRING (val );
457459 drop_leading_backslash (val );
458460 opline -> op2 .constant = zend_optimizer_add_literal (op_array , val );
459- zend_optimizer_add_literal_string (op_array , zend_string_tolower (Z_STR_P (val )));
461+ zend_string_addref (Z_STR_P (val ));
462+ zend_optimizer_add_literal_string (op_array , Z_STR_P (val ));
460463 if (opline -> op1_type != IS_CONST ) {
461464 opline -> extended_value = alloc_cache_slots (op_array , 1 ) | (opline -> extended_value & (ZEND_RETURNS_FUNCTION |ZEND_ISEMPTY |ZEND_FETCH_OBJ_FLAGS ));
462465 }
463466 break ;
464467 case ZEND_INIT_FCALL :
465468 REQUIRES_STRING (val );
466- if (Z_REFCOUNT_P (val ) == 1 ) {
467- zend_str_tolower (Z_STRVAL_P (val ), Z_STRLEN_P (val ));
468- } else {
469- ZVAL_STR (& tmp , zend_string_tolower (Z_STR_P (val )));
470- zval_ptr_dtor_nogc (val );
471- val = & tmp ;
472- }
473469 opline -> op2 .constant = zend_optimizer_add_literal (op_array , val );
474470 opline -> result .num = alloc_cache_slots (op_array , 1 );
475471 break ;
@@ -488,7 +484,6 @@ bool zend_optimizer_update_op2_const(zend_op_array *op_array,
488484 opline -> opcode = ZEND_INIT_FCALL_BY_NAME ;
489485 drop_leading_backslash (val );
490486 opline -> op2 .constant = zend_optimizer_add_literal (op_array , val );
491- zend_optimizer_add_literal_string (op_array , zend_string_tolower (Z_STR_P (val )));
492487 opline -> result .num = alloc_cache_slots (op_array , 1 );
493488 } else {
494489 opline -> op2 .constant = zend_optimizer_add_literal (op_array , val );
@@ -497,13 +492,11 @@ bool zend_optimizer_update_op2_const(zend_op_array *op_array,
497492 case ZEND_INIT_METHOD_CALL :
498493 REQUIRES_STRING (val );
499494 opline -> op2 .constant = zend_optimizer_add_literal (op_array , val );
500- zend_optimizer_add_literal_string (op_array , zend_string_tolower (Z_STR_P (val )));
501495 opline -> result .num = alloc_cache_slots (op_array , 2 );
502496 break ;
503497 case ZEND_INIT_STATIC_METHOD_CALL :
504498 REQUIRES_STRING (val );
505499 opline -> op2 .constant = zend_optimizer_add_literal (op_array , val );
506- zend_optimizer_add_literal_string (op_array , zend_string_tolower (Z_STR_P (val )));
507500 if (opline -> op1_type != IS_CONST ) {
508501 opline -> result .num = alloc_cache_slots (op_array , 2 );
509502 }
@@ -922,9 +915,8 @@ zend_function *zend_optimizer_get_called_func(
922915 break ;
923916 }
924917 case ZEND_INIT_FCALL_BY_NAME :
925- case ZEND_INIT_NS_FCALL_BY_NAME :
926918 if (opline -> op2_type == IS_CONST && Z_TYPE_P (CRT_CONSTANT (opline -> op2 )) == IS_STRING ) {
927- const zval * function_name = CRT_CONSTANT (opline -> op2 ) + 1 ;
919+ const zval * function_name = CRT_CONSTANT (opline -> op2 );
928920 zend_function * func ;
929921 zval * func_zv ;
930922 if (script && (func = zend_hash_find_ptr (& script -> function_table , Z_STR_P (function_name )))) {
@@ -936,12 +928,39 @@ zend_function *zend_optimizer_get_called_func(
936928 }
937929 }
938930 break ;
931+ case ZEND_INIT_NS_FCALL_BY_NAME :
932+ if (opline -> op2_type == IS_CONST && Z_TYPE_P (CRT_CONSTANT (opline -> op2 )) == IS_STRING ) {
933+ /* slot 0 = ns-qualified name, slot 1 = unqualified fallback */
934+ const zval * ns_name = CRT_CONSTANT (opline -> op2 );
935+ const zval * unqualified_name = CRT_CONSTANT (opline -> op2 ) + 1 ;
936+ zend_function * func ;
937+ zval * func_zv ;
938+ /* Try ns-qualified first */
939+ if (script && (func = zend_hash_find_ptr (& script -> function_table , Z_STR_P (ns_name )))) {
940+ return func ;
941+ } else if ((func_zv = zend_hash_find (EG (function_table ), Z_STR_P (ns_name ))) != NULL ) {
942+ if (!zend_optimizer_ignore_function (func_zv , op_array -> filename )) {
943+ return Z_PTR_P (func_zv );
944+ }
945+ }
946+ /* Fall back to unqualified global name */
947+ if (Z_TYPE_P (unqualified_name ) == IS_STRING ) {
948+ if (script && (func = zend_hash_find_ptr (& script -> function_table , Z_STR_P (unqualified_name )))) {
949+ return func ;
950+ } else if ((func_zv = zend_hash_find (EG (function_table ), Z_STR_P (unqualified_name ))) != NULL ) {
951+ if (!zend_optimizer_ignore_function (func_zv , op_array -> filename )) {
952+ return Z_PTR_P (func_zv );
953+ }
954+ }
955+ }
956+ }
957+ break ;
939958 case ZEND_INIT_STATIC_METHOD_CALL :
940959 if (opline -> op2_type == IS_CONST && Z_TYPE_P (CRT_CONSTANT (opline -> op2 )) == IS_STRING ) {
941960 const zend_class_entry * ce = zend_optimizer_get_class_entry_from_op1 (
942961 script , op_array , opline );
943962 if (ce ) {
944- zend_string * func_name = Z_STR_P (CRT_CONSTANT (opline -> op2 ) + 1 );
963+ zend_string * func_name = Z_STR_P (CRT_CONSTANT (opline -> op2 ));
945964 zend_function * fbc = zend_hash_find_ptr (& ce -> function_table , func_name );
946965 if (fbc && !(fbc -> common .fn_flags & ZEND_ACC_ABSTRACT )) {
947966 bool is_public = (fbc -> common .fn_flags & ZEND_ACC_PUBLIC ) != 0 ;
@@ -959,7 +978,7 @@ zend_function *zend_optimizer_get_called_func(
959978 && op_array -> scope
960979 && !(op_array -> fn_flags & ZEND_ACC_TRAIT_CLONE )
961980 && !(op_array -> scope -> ce_flags & ZEND_ACC_TRAIT )) {
962- zend_string * method_name = Z_STR_P (CRT_CONSTANT (opline -> op2 ) + 1 );
981+ zend_string * method_name = Z_STR_P (CRT_CONSTANT (opline -> op2 ));
963982 zend_function * fbc = zend_hash_find_ptr (
964983 & op_array -> scope -> function_table , method_name );
965984 if (fbc ) {
0 commit comments