Skip to content

Commit 469df0e

Browse files
committed
Clean up hack to avoid opcode emission for closures in const-expr
1 parent 94f42ef commit 469df0e

File tree

1 file changed

+22
-20
lines changed

1 file changed

+22
-20
lines changed

Zend/zend_compile.c

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8138,7 +8138,13 @@ static uint32_t zend_add_dynamic_func_def(zend_op_array *def) {
81388138
return def_offset;
81398139
}
81408140

8141-
static zend_string *zend_begin_func_decl(znode *result, zend_op_array *op_array, zend_ast_decl *decl, bool toplevel) /* {{{ */
8141+
enum func_decl_level {
8142+
FUNC_DECL_LEVEL_TOPLEVEL,
8143+
FUNC_DECL_LEVEL_NESTED,
8144+
FUNC_DECL_LEVEL_CONSTEXPR,
8145+
};
8146+
8147+
static zend_string *zend_begin_func_decl(znode *result, zend_op_array *op_array, zend_ast_decl *decl, enum func_decl_level level) /* {{{ */
81428148
{
81438149
zend_string *unqualified_name, *name, *lcname;
81448150
zend_op *opline;
@@ -8208,9 +8214,9 @@ static zend_string *zend_begin_func_decl(znode *result, zend_op_array *op_array,
82088214
}
82098215

82108216
zend_register_seen_symbol(lcname, ZEND_SYMBOL_FUNCTION);
8211-
if (!toplevel) {
8217+
if (level != FUNC_DECL_LEVEL_TOPLEVEL) {
82128218
uint32_t func_ref = zend_add_dynamic_func_def(op_array);
8213-
if (decl->kind != ZEND_AST_OP_ARRAY) {
8219+
if (level != FUNC_DECL_LEVEL_CONSTEXPR) {
82148220
if (op_array->fn_flags & ZEND_ACC_CLOSURE) {
82158221
opline = zend_emit_op_tmp(result, ZEND_DECLARE_LAMBDA_FUNCTION, NULL, NULL);
82168222
opline->op2.num = func_ref;
@@ -8228,7 +8234,7 @@ static zend_string *zend_begin_func_decl(znode *result, zend_op_array *op_array,
82288234
/* }}} */
82298235

82308236
static zend_op_array *zend_compile_func_decl_ex(
8231-
znode *result, zend_ast *ast, bool toplevel,
8237+
znode *result, zend_ast *ast, enum func_decl_level level,
82328238
const zend_property_info *property_info,
82338239
zend_property_hook_kind hook_kind
82348240
) {
@@ -8262,7 +8268,7 @@ static zend_op_array *zend_compile_func_decl_ex(
82628268
op_array->doc_comment = zend_string_copy(decl->doc_comment);
82638269
}
82648270

8265-
if (decl->kind == ZEND_AST_CLOSURE || decl->kind == ZEND_AST_ARROW_FUNC || decl->kind == ZEND_AST_OP_ARRAY) {
8271+
if (decl->kind == ZEND_AST_CLOSURE || decl->kind == ZEND_AST_ARROW_FUNC) {
82668272
op_array->fn_flags |= ZEND_ACC_CLOSURE;
82678273
}
82688274

@@ -8274,7 +8280,7 @@ static zend_op_array *zend_compile_func_decl_ex(
82748280
bool has_body = stmt_ast != NULL;
82758281
lcname = zend_begin_method_decl(op_array, decl->name, has_body);
82768282
} else {
8277-
lcname = zend_begin_func_decl(result, op_array, decl, toplevel);
8283+
lcname = zend_begin_func_decl(result, op_array, decl, level);
82788284
if (decl->kind == ZEND_AST_ARROW_FUNC) {
82798285
find_implicit_binds(&info, params_ast, stmt_ast);
82808286
compile_implicit_lexical_binds(&info, result, op_array);
@@ -8322,7 +8328,7 @@ static zend_op_array *zend_compile_func_decl_ex(
83228328
CG(active_class_entry) = NULL;
83238329
}
83248330

8325-
if (toplevel) {
8331+
if (level == FUNC_DECL_LEVEL_TOPLEVEL) {
83268332
op_array->fn_flags |= ZEND_ACC_TOP_LEVEL;
83278333
}
83288334

@@ -8369,7 +8375,7 @@ static zend_op_array *zend_compile_func_decl_ex(
83698375
CG(zend_lineno) = decl->start_lineno;
83708376
zend_check_magic_method_implementation(
83718377
CG(active_class_entry), (zend_function *) op_array, lcname, E_COMPILE_ERROR);
8372-
} else if (toplevel) {
8378+
} else if (level == FUNC_DECL_LEVEL_TOPLEVEL) {
83738379
/* Only register the function after a successful compile */
83748380
if (UNEXPECTED(zend_hash_add_ptr(CG(function_table), lcname, op_array) == NULL)) {
83758381
CG(zend_lineno) = decl->start_lineno;
@@ -8389,7 +8395,7 @@ static zend_op_array *zend_compile_func_decl_ex(
83898395
/* Pop the loop variable stack separator */
83908396
zend_stack_del_top(&CG(loop_var_stack));
83918397

8392-
if (toplevel) {
8398+
if (level == FUNC_DECL_LEVEL_TOPLEVEL) {
83938399
zend_observer_function_declared_notify(op_array, lcname);
83948400
}
83958401

@@ -8403,9 +8409,9 @@ static zend_op_array *zend_compile_func_decl_ex(
84038409
return op_array;
84048410
}
84058411

8406-
static zend_op_array *zend_compile_func_decl(znode *result, zend_ast *ast, bool toplevel)
8412+
static zend_op_array *zend_compile_func_decl(znode *result, zend_ast *ast, enum func_decl_level level)
84078413
{
8408-
return zend_compile_func_decl_ex(result, ast, toplevel, /* property_info */ NULL, (zend_property_hook_kind)-1);
8414+
return zend_compile_func_decl_ex(result, ast, level, /* property_info */ NULL, (zend_property_hook_kind)-1);
84098415
}
84108416

84118417
zend_property_hook_kind zend_get_property_hook_kind_from_name(zend_string *name) {
@@ -8544,7 +8550,7 @@ static void zend_compile_property_hooks(
85448550
hook->name = zend_strpprintf(0, "$%s::%s", ZSTR_VAL(prop_name), ZSTR_VAL(name));
85458551

85468552
zend_function *func = (zend_function *) zend_compile_func_decl_ex(
8547-
NULL, (zend_ast *) hook, /* toplevel */ false, prop_info, hook_kind);
8553+
NULL, (zend_ast *) hook, FUNC_DECL_LEVEL_NESTED, prop_info, hook_kind);
85488554

85498555
func->common.prop_info = prop_info;
85508556

@@ -11200,11 +11206,7 @@ static void zend_compile_const_expr_closure(zend_ast **ast_ptr)
1120011206
}
1120111207

1120211208
znode node;
11203-
zend_ast *ast = *ast_ptr;
11204-
zend_ast_kind old_kind = ast->kind;
11205-
ast->kind = ZEND_AST_OP_ARRAY;
11206-
zend_op_array *op = zend_compile_func_decl(&node, ast, /* toplevel */ false);
11207-
ast->kind = old_kind;
11209+
zend_op_array *op = zend_compile_func_decl(&node, *ast_ptr, FUNC_DECL_LEVEL_CONSTEXPR);
1120811210

1120911211
zend_ast_destroy(*ast_ptr);
1121011212
zval z;
@@ -11320,7 +11322,7 @@ void zend_compile_top_stmt(zend_ast *ast) /* {{{ */
1132011322

1132111323
if (ast->kind == ZEND_AST_FUNC_DECL) {
1132211324
CG(zend_lineno) = ast->lineno;
11323-
zend_compile_func_decl(NULL, ast, 1);
11325+
zend_compile_func_decl(NULL, ast, FUNC_DECL_LEVEL_TOPLEVEL);
1132411326
CG(zend_lineno) = ((zend_ast_decl *) ast)->end_lineno;
1132511327
} else if (ast->kind == ZEND_AST_CLASS) {
1132611328
CG(zend_lineno) = ast->lineno;
@@ -11402,7 +11404,7 @@ static void zend_compile_stmt(zend_ast *ast) /* {{{ */
1140211404
break;
1140311405
case ZEND_AST_FUNC_DECL:
1140411406
case ZEND_AST_METHOD:
11405-
zend_compile_func_decl(NULL, ast, 0);
11407+
zend_compile_func_decl(NULL, ast, FUNC_DECL_LEVEL_NESTED);
1140611408
break;
1140711409
case ZEND_AST_ENUM_CASE:
1140811410
zend_compile_enum_case(ast);
@@ -11579,7 +11581,7 @@ static void zend_compile_expr_inner(znode *result, zend_ast *ast) /* {{{ */
1157911581
return;
1158011582
case ZEND_AST_CLOSURE:
1158111583
case ZEND_AST_ARROW_FUNC:
11582-
zend_compile_func_decl(result, ast, 0);
11584+
zend_compile_func_decl(result, ast, FUNC_DECL_LEVEL_NESTED);
1158311585
return;
1158411586
case ZEND_AST_THROW:
1158511587
zend_compile_throw(result, ast);

0 commit comments

Comments
 (0)