@@ -2531,6 +2531,47 @@ static zend_never_inline void ZEND_FASTCALL init_func_run_time_cache(zend_op_arr
2531
2531
}
2532
2532
/* }}} */
2533
2533
2534
+ static zend_always_inline zend_function * ZEND_FASTCALL init_func_run_time_cache_i (zend_op_array * op_array , zval * zv ) /* {{{ */
2535
+ {
2536
+ ZEND_ASSERT (op_array -> run_time_cache == NULL );
2537
+ if (op_array -> fn_flags & ZEND_ACC_IMMUTABLE ) {
2538
+ zend_op_array * new_op_array = zend_arena_alloc (& CG (arena ), sizeof (zend_op_array ) + op_array -> cache_size );
2539
+
2540
+ Z_PTR_P (zv ) = new_op_array ;
2541
+ memcpy (new_op_array , op_array , sizeof (zend_op_array ));
2542
+ new_op_array -> fn_flags &= ~ZEND_ACC_IMMUTABLE ;
2543
+ new_op_array -> run_time_cache = (void * * )(new_op_array + 1 );
2544
+ memset (new_op_array -> run_time_cache , 0 , new_op_array -> cache_size );
2545
+ return (zend_function * )new_op_array ;
2546
+ } else {
2547
+ op_array -> run_time_cache = zend_arena_alloc (& CG (arena ), op_array -> cache_size );
2548
+ memset (op_array -> run_time_cache , 0 , op_array -> cache_size );
2549
+ return (zend_function * )op_array ;
2550
+ }
2551
+ }
2552
+ /* }}} */
2553
+
2554
+ static zend_never_inline zend_function * ZEND_FASTCALL init_func_run_time_cache_ex (zend_op_array * op_array , zval * zv ) /* {{{ */
2555
+ {
2556
+ return init_func_run_time_cache_i (op_array , zv );
2557
+ }
2558
+ /* }}} */
2559
+
2560
+ ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function (zend_string * name ) /* {{{ */
2561
+ {
2562
+ zval * zv = zend_hash_find (EG (function_table ), name );
2563
+
2564
+ if (EXPECTED (zv != NULL )) {
2565
+ zend_function * fbc = Z_FUNC_P (zv );
2566
+
2567
+ if (EXPECTED (fbc -> type == ZEND_USER_FUNCTION ) && UNEXPECTED (!fbc -> op_array .run_time_cache )) {
2568
+ fbc = (zend_function * )init_func_run_time_cache_i (& fbc -> op_array , zv );
2569
+ }
2570
+ return fbc ;
2571
+ }
2572
+ return NULL ;
2573
+ } /* }}} */
2574
+
2534
2575
static zend_always_inline void i_init_code_execute_data (zend_execute_data * execute_data , zend_op_array * op_array , zval * return_value ) /* {{{ */
2535
2576
{
2536
2577
ZEND_ASSERT (EX (func ) == (zend_function * )op_array );
@@ -2563,8 +2604,7 @@ ZEND_API void zend_init_func_execute_data(zend_execute_data *ex, zend_op_array *
2563
2604
2564
2605
EX (prev_execute_data ) = EG (current_execute_data );
2565
2606
if (!op_array -> run_time_cache ) {
2566
- op_array -> run_time_cache = zend_arena_alloc (& CG (arena ), op_array -> cache_size );
2567
- memset (op_array -> run_time_cache , 0 , op_array -> cache_size );
2607
+ init_func_run_time_cache (op_array );
2568
2608
}
2569
2609
i_init_func_execute_data (op_array , return_value , 1 EXECUTE_DATA_CC );
2570
2610
@@ -2924,6 +2964,9 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_string(zend_s
2924
2964
return NULL ;
2925
2965
}
2926
2966
}
2967
+ if (EXPECTED (fbc -> type == ZEND_USER_FUNCTION ) && UNEXPECTED (!fbc -> op_array .run_time_cache )) {
2968
+ init_func_run_time_cache (& fbc -> op_array );
2969
+ }
2927
2970
} else {
2928
2971
if (ZSTR_VAL (function )[0 ] == '\\' ) {
2929
2972
lcname = zend_string_alloc (ZSTR_LEN (function ) - 1 , 0 );
@@ -2939,13 +2982,12 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_string(zend_s
2939
2982
zend_string_release_ex (lcname , 0 );
2940
2983
2941
2984
fbc = Z_FUNC_P (func );
2985
+ if (EXPECTED (fbc -> type == ZEND_USER_FUNCTION ) && UNEXPECTED (!fbc -> op_array .run_time_cache )) {
2986
+ fbc = init_func_run_time_cache_ex (& fbc -> op_array , func );
2987
+ }
2942
2988
called_scope = NULL ;
2943
2989
}
2944
2990
2945
- if (EXPECTED (fbc -> type == ZEND_USER_FUNCTION ) && UNEXPECTED (!fbc -> op_array .run_time_cache )) {
2946
- init_func_run_time_cache (& fbc -> op_array );
2947
- }
2948
-
2949
2991
return zend_vm_stack_push_call_frame (ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC ,
2950
2992
fbc , num_args , called_scope , NULL );
2951
2993
}
0 commit comments