Skip to content

Commit 842681f

Browse files
committed
Store the declaring op_array in FCC/PFA const exprs AST
This will be useful when compiling the PFA, as zend_partial_create() needs it.
1 parent ba99bcb commit 842681f

6 files changed

Lines changed: 31 additions & 9 deletions

File tree

Zend/zend_ast.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_fcc(zend_ast *args) {
6060
ast->kind = ZEND_AST_CALLABLE_CONVERT;
6161
ast->attr = 0;
6262
ast->lineno = CG(zend_lineno);
63+
ast->declaring_op_array = NULL;
6364
ast->args = args;
6465
ZEND_MAP_PTR_INIT(ast->fptr, NULL);
6566

@@ -1425,6 +1426,7 @@ static void* ZEND_FASTCALL zend_ast_tree_copy(zend_ast *ast, void *buf)
14251426
new->kind = old->kind;
14261427
new->attr = old->attr;
14271428
new->lineno = old->lineno;
1429+
new->declaring_op_array = old->declaring_op_array;
14281430
ZEND_MAP_PTR_INIT(new->fptr, ZEND_MAP_PTR(old->fptr));
14291431
buf = (void*)((char*)buf + sizeof(zend_ast_fcc));
14301432
new->args = buf;

Zend/zend_ast.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ typedef struct _zend_ast_fcc {
233233
zend_ast_kind kind; /* Type of the node (ZEND_AST_* enum constant) */
234234
zend_ast_attr attr; /* Additional attribute, use depending on node type */
235235
uint32_t lineno; /* Line number */
236+
zend_op_array *declaring_op_array;
236237
zend_ast *args;
237238
ZEND_MAP_PTR_DEF(zend_function *, fptr);
238239
} zend_ast_fcc;

Zend/zend_compile.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12021,11 +12021,8 @@ static void zend_compile_const_expr_fcc(zend_ast **ast_ptr)
1202112021
zend_error_noreturn(E_COMPILE_ERROR, "Constant expression contains invalid operations");
1202212022
}
1202312023

12024-
zend_ast_list *args = zend_ast_get_list(((zend_ast_fcc*)*args_ast)->args);
12025-
if (args->children != 1 || args->child[0]->attr != ZEND_PLACEHOLDER_VARIADIC) {
12026-
// TODO: PFAs
12027-
zend_error_noreturn(E_COMPILE_ERROR, "Constant expression contains invalid operations");
12028-
}
12024+
zend_ast_fcc *fcc = (zend_ast_fcc*)*args_ast;
12025+
fcc->declaring_op_array = CG(active_op_array);
1202912026

1203012027
switch ((*ast_ptr)->kind) {
1203112028
case ZEND_AST_CALL: {

ext/opcache/ZendAccelerator.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ typedef struct _zend_accel_globals {
222222
/* preallocated shared-memory block to save current script */
223223
void *mem;
224224
zend_persistent_script *current_persistent_script;
225+
zend_op_array *current_persistent_op_array;
225226
/* cache to save hash lookup on the same INCLUDE opcode */
226227
const zend_op *cache_opline;
227228
zend_persistent_script *cache_persistent_script;

ext/opcache/zend_file_cache.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1308,6 +1308,7 @@ static void zend_file_cache_unserialize_ast(zend_ast *ast,
13081308
zend_ast_get_op_array(ast)->op_array = Z_PTR(z);
13091309
} else if (ast->kind == ZEND_AST_CALLABLE_CONVERT) {
13101310
zend_ast_fcc *fcc = (zend_ast_fcc*)ast;
1311+
fcc->declaring_op_array = CG(active_op_array);
13111312
ZEND_MAP_PTR_NEW(fcc->fptr);
13121313
if (!IS_UNSERIALIZED(fcc->args)) {
13131314
UNSERIALIZE_PTR(fcc->args);
@@ -1414,6 +1415,9 @@ static void zend_file_cache_unserialize_op_array(zend_op_array *op_arr
14141415
zend_persistent_script *script,
14151416
void *buf)
14161417
{
1418+
zend_op_array *orig_op_array = CG(active_op_array);
1419+
CG(active_op_array) = op_array;
1420+
14171421
if (!script->corrupted) {
14181422
if (op_array != &script->script.main_op_array) {
14191423
op_array->fn_flags |= ZEND_ACC_IMMUTABLE;
@@ -1434,7 +1438,7 @@ static void zend_file_cache_unserialize_op_array(zend_op_array *op_arr
14341438
/* Check whether this op_array has already been unserialized. */
14351439
if (IS_UNSERIALIZED(op_array->opcodes)) {
14361440
ZEND_ASSERT(op_array->scope && "Only method op_arrays should be shared");
1437-
return;
1441+
goto end;
14381442
}
14391443

14401444
if (op_array->refcount) {
@@ -1453,7 +1457,7 @@ static void zend_file_cache_unserialize_op_array(zend_op_array *op_arr
14531457
UNSERIALIZE_PTR(op_array->try_catch_array);
14541458
UNSERIALIZE_PTR(op_array->prototype);
14551459
UNSERIALIZE_PTR(op_array->prop_info);
1456-
return;
1460+
goto end;
14571461
}
14581462

14591463
if (op_array->static_variables) {
@@ -1597,6 +1601,9 @@ static void zend_file_cache_unserialize_op_array(zend_op_array *op_arr
15971601
UNSERIALIZE_PTR(op_array->prototype);
15981602
UNSERIALIZE_PTR(op_array->prop_info);
15991603
}
1604+
1605+
end:
1606+
CG(active_op_array) = orig_op_array;
16001607
}
16011608

16021609
static void zend_file_cache_unserialize_func(zval *zv,
@@ -1888,6 +1895,9 @@ static void zend_file_cache_unserialize(zend_persistent_script *script,
18881895
{
18891896
script->mem = buf;
18901897

1898+
zend_op_array *orig_op_array = CG(active_op_array);
1899+
CG(active_op_array) = &script->script.main_op_array;
1900+
18911901
UNSERIALIZE_STR(script->script.filename);
18921902

18931903
zend_file_cache_unserialize_hash(&script->script.class_table,
@@ -1897,6 +1907,8 @@ static void zend_file_cache_unserialize(zend_persistent_script *script,
18971907
zend_file_cache_unserialize_op_array(&script->script.main_op_array, script, buf);
18981908
zend_file_cache_unserialize_warnings(script, buf);
18991909
zend_file_cache_unserialize_early_bindings(script, buf);
1910+
1911+
CG(active_op_array) = orig_op_array;
19001912
}
19011913

19021914
static zend_persistent_script file_cache_validate_success_script;

ext/opcache/zend_persist.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,8 @@ static zend_ast *zend_persist_ast(zend_ast *ast)
195195
node = (zend_ast *) copy;
196196
} else if (ast->kind == ZEND_AST_CALLABLE_CONVERT) {
197197
zend_ast_fcc *copy = zend_shared_memdup(ast, sizeof(zend_ast_fcc));
198+
ZEND_ASSERT(ZCG(current_persistent_op_array));
199+
copy->declaring_op_array = ZCG(current_persistent_op_array);
198200
copy->args = zend_persist_ast(copy->args);
199201
ZEND_MAP_PTR_NEW(copy->fptr);
200202
node = (zend_ast *) copy;
@@ -393,6 +395,9 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
393395
zend_op *persist_ptr;
394396
zval *orig_literals = NULL;
395397

398+
zend_op_array *orig_persistent_op_array = ZCG(current_persistent_op_array);
399+
ZCG(current_persistent_op_array) = op_array;
400+
396401
if (op_array->refcount && --(*op_array->refcount) == 0) {
397402
efree(op_array->refcount);
398403
}
@@ -494,7 +499,7 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
494499
ZEND_ASSERT(op_array->dynamic_func_defs != NULL);
495500
}
496501
ZCG(mem) = (void*)((char*)ZCG(mem) + ZEND_ALIGNED_SIZE(zend_extensions_op_array_persist(op_array, ZCG(mem))));
497-
return;
502+
goto end;
498503
}
499504
} else {
500505
/* "prototype" may be undefined if "scope" isn't set */
@@ -504,7 +509,7 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
504509
if (op_array->scope
505510
&& !(op_array->fn_flags & ZEND_ACC_CLOSURE)
506511
&& (op_array->scope->ce_flags & ZEND_ACC_CACHED)) {
507-
return;
512+
goto end;
508513
}
509514

510515
if (op_array->static_variables && !zend_accel_in_shm(op_array->static_variables)) {
@@ -701,6 +706,8 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
701706
}
702707

703708
ZCG(mem) = (void*)((char*)ZCG(mem) + ZEND_ALIGNED_SIZE(zend_extensions_op_array_persist(op_array, ZCG(mem))));
709+
end:
710+
ZCG(current_persistent_op_array) = orig_persistent_op_array;
704711
}
705712

706713
static void zend_persist_op_array(zval *zv)
@@ -1433,6 +1440,7 @@ zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script
14331440
script = zend_shared_memdup_free(script, sizeof(zend_persistent_script));
14341441
script->corrupted = false;
14351442
ZCG(current_persistent_script) = script;
1443+
ZCG(current_persistent_op_array) = &script->script.main_op_array;
14361444

14371445
if (!for_shm) {
14381446
/* script is not going to be saved in SHM */
@@ -1495,6 +1503,7 @@ zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script
14951503

14961504
script->corrupted = false;
14971505
ZCG(current_persistent_script) = NULL;
1506+
ZCG(current_persistent_op_array) = NULL;
14981507

14991508
return script;
15001509
}

0 commit comments

Comments
 (0)