@@ -3321,6 +3321,12 @@ int zend_compile_func_ord(znode *result, zend_ast_list *args) /* {{{ */
3321
3321
}
3322
3322
/* }}} */
3323
3323
3324
+ /* We can only calculate the stack size for functions that have been fully compiled, otherwise
3325
+ * additional CV or TMP slots may still be added. This prevents the use of INIT_FCALL for
3326
+ * directly or indirectly recursive function calls. */
3327
+ static zend_bool fbc_is_finalized (zend_function * fbc ) {
3328
+ return !ZEND_USER_CODE (fbc -> type ) || (fbc -> common .fn_flags & ZEND_ACC_DONE_PASS_TWO );
3329
+ }
3324
3330
3325
3331
static int zend_try_compile_ct_bound_init_user_func (zend_ast * name_ast , uint32_t num_args ) /* {{{ */
3326
3332
{
@@ -3336,9 +3342,7 @@ static int zend_try_compile_ct_bound_init_user_func(zend_ast *name_ast, uint32_t
3336
3342
lcname = zend_string_tolower (name );
3337
3343
3338
3344
fbc = zend_hash_find_ptr (CG (function_table ), lcname );
3339
- if (!fbc
3340
- /* Don't use INIT_FCALL for recursive calls */
3341
- || (fbc == (zend_function * )CG (active_op_array ))
3345
+ if (!fbc || !fbc_is_finalized (fbc )
3342
3346
|| (fbc -> type == ZEND_INTERNAL_FUNCTION && (CG (compiler_options ) & ZEND_COMPILE_IGNORE_INTERNAL_FUNCTIONS ))
3343
3347
|| (fbc -> type == ZEND_USER_FUNCTION && (CG (compiler_options ) & ZEND_COMPILE_IGNORE_USER_FUNCTIONS ))
3344
3348
|| (fbc -> type == ZEND_USER_FUNCTION && (CG (compiler_options ) & ZEND_COMPILE_IGNORE_OTHER_FILES ) && fbc -> op_array .filename != CG (active_op_array )-> filename )
@@ -3461,8 +3465,7 @@ static void zend_compile_assert(znode *result, zend_ast_list *args, zend_string
3461
3465
3462
3466
zend_emit_op (NULL , ZEND_ASSERT_CHECK , NULL , NULL );
3463
3467
3464
- /* Don't use INIT_FCALL for recursive calls */
3465
- if (fbc && fbc != (zend_function * )CG (active_op_array )) {
3468
+ if (fbc && fbc_is_finalized (fbc )) {
3466
3469
name_node .op_type = IS_CONST ;
3467
3470
ZVAL_STR_COPY (& name_node .u .constant , name );
3468
3471
@@ -3838,9 +3841,7 @@ void zend_compile_call(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
3838
3841
return ;
3839
3842
}
3840
3843
3841
- if (!fbc
3842
- /* Don't use INIT_FCALL for recursive calls */
3843
- || (fbc == (zend_function * )CG (active_op_array ))
3844
+ if (!fbc || !fbc_is_finalized (fbc )
3844
3845
|| (fbc -> type == ZEND_INTERNAL_FUNCTION && (CG (compiler_options ) & ZEND_COMPILE_IGNORE_INTERNAL_FUNCTIONS ))
3845
3846
|| (fbc -> type == ZEND_USER_FUNCTION && (CG (compiler_options ) & ZEND_COMPILE_IGNORE_USER_FUNCTIONS ))
3846
3847
|| (fbc -> type == ZEND_USER_FUNCTION && (CG (compiler_options ) & ZEND_COMPILE_IGNORE_OTHER_FILES ) && fbc -> op_array .filename != CG (active_op_array )-> filename )
0 commit comments