mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Support PFA syntax
RFC: https://wiki.php.net/rfc/partial_function_application_v2 For FCCs, the parser generates a normal function call AST node, the but argument list is a ZEND_AST_CALLABLE_CONVERT / zend_ast_fcc node. We extend this for PFAs so that zend_ast_fcc can represent arguments. * Support PFA syntax in grammar * Update zend_ast_fcc so that arguments can be represented * Support serialization of zend_ast_fcc arguments in SHM / file cache * Introduce zend_ast_arg_list_add(): Same as zend_ast_list_add(), but wraps the list in a ZEND_AST_CALLABLE_CONVERT when adding any placeholder argument. Technically the arg list wrapping is not required, but it results in simpler code later as it will be very convenient in the compiler (determines whether a function calls is a PFA/FCC), and for PFA-in-const-expr support. It also allows to unify FCCs and PFAs in the grammar. Closes GH-20717.
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
--TEST--
|
||||
First class callable error: more than one argument
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
foo(1, ...);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot create a Closure for call expression with more than one argument, or non-variadic placeholders in %s on line %d
|
||||
@@ -0,0 +1,10 @@
|
||||
--TEST--
|
||||
First class callable error: non-variadic placeholder
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
foo(?);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot create a Closure for call expression with more than one argument, or non-variadic placeholders in %s on line %d
|
||||
127
Zend/zend_ast.c
127
Zend/zend_ast.c
@@ -54,13 +54,14 @@ ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_znode(const znode *node) {
|
||||
return (zend_ast *) ast;
|
||||
}
|
||||
|
||||
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_fcc(void) {
|
||||
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_fcc(zend_ast *args) {
|
||||
zend_ast_fcc *ast;
|
||||
|
||||
ast = zend_ast_alloc(sizeof(zend_ast_fcc));
|
||||
ast->kind = ZEND_AST_CALLABLE_CONVERT;
|
||||
ast->attr = 0;
|
||||
ast->lineno = CG(zend_lineno);
|
||||
ast->args = args;
|
||||
ZEND_MAP_PTR_INIT(ast->fptr, NULL);
|
||||
|
||||
return (zend_ast *) ast;
|
||||
@@ -157,6 +158,12 @@ ZEND_API zend_ast *zend_ast_create_decl(
|
||||
return (zend_ast *) ast;
|
||||
}
|
||||
|
||||
static bool zend_ast_is_placeholder_arg(zend_ast *arg) {
|
||||
return arg->kind == ZEND_AST_PLACEHOLDER_ARG
|
||||
|| (arg->kind == ZEND_AST_NAMED_ARG
|
||||
&& arg->child[1]->kind == ZEND_AST_PLACEHOLDER_ARG);
|
||||
}
|
||||
|
||||
#if ZEND_AST_SPEC
|
||||
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_0(zend_ast_kind kind) {
|
||||
zend_ast *ast;
|
||||
@@ -400,6 +407,30 @@ ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_2(zend_ast_kind kind, zen
|
||||
|
||||
return ast;
|
||||
}
|
||||
|
||||
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_arg_list_0(zend_ast_kind kind) {
|
||||
return zend_ast_create_list(0, kind);
|
||||
}
|
||||
|
||||
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_arg_list_1(zend_ast_kind kind, zend_ast *arg) {
|
||||
zend_ast *list = zend_ast_create_list(1, kind, arg);
|
||||
|
||||
if (zend_ast_is_placeholder_arg(arg)) {
|
||||
return zend_ast_create_fcc(list);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_arg_list_2(zend_ast_kind kind, zend_ast *arg1, zend_ast *arg2) {
|
||||
zend_ast *list = zend_ast_create_list(2, kind, arg1, arg2);
|
||||
|
||||
if (zend_ast_is_placeholder_arg(arg1) || zend_ast_is_placeholder_arg(arg2)) {
|
||||
return zend_ast_create_fcc(list);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
#else
|
||||
static zend_ast *zend_ast_create_from_va_list(zend_ast_kind kind, zend_ast_attr attr, va_list va) {
|
||||
uint32_t i, children = kind >> ZEND_AST_NUM_CHILDREN_SHIFT;
|
||||
@@ -479,6 +510,41 @@ ZEND_API zend_ast *zend_ast_create_list(uint32_t init_children, zend_ast_kind ki
|
||||
|
||||
return ast;
|
||||
}
|
||||
|
||||
ZEND_API zend_ast *zend_ast_create_arg_list(uint32_t init_children, zend_ast_kind kind, ...) {
|
||||
zend_ast *ast;
|
||||
zend_ast_list *list;
|
||||
bool has_placeholders = false;
|
||||
|
||||
ast = zend_ast_alloc(zend_ast_list_size(4));
|
||||
list = (zend_ast_list *) ast;
|
||||
list->kind = kind;
|
||||
list->attr = 0;
|
||||
list->lineno = CG(zend_lineno);
|
||||
list->children = 0;
|
||||
|
||||
{
|
||||
va_list va;
|
||||
uint32_t i;
|
||||
va_start(va, kind);
|
||||
for (i = 0; i < init_children; ++i) {
|
||||
zend_ast *child = va_arg(va, zend_ast *);
|
||||
ast = zend_ast_list_add(ast, child);
|
||||
uint32_t lineno = zend_ast_get_lineno(child);
|
||||
if (lineno < ast->lineno) {
|
||||
ast->lineno = lineno;
|
||||
}
|
||||
has_placeholders = has_placeholders || zend_ast_is_placeholder_arg(child);
|
||||
}
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
if (has_placeholders) {
|
||||
return zend_ast_create_fcc(list);
|
||||
}
|
||||
|
||||
return ast;
|
||||
}
|
||||
#endif
|
||||
|
||||
zend_ast *zend_ast_create_concat_op(zend_ast *op0, zend_ast *op1) {
|
||||
@@ -508,6 +574,23 @@ ZEND_ATTRIBUTE_NODISCARD ZEND_API zend_ast * ZEND_FASTCALL zend_ast_list_add(zen
|
||||
return (zend_ast *) list;
|
||||
}
|
||||
|
||||
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_arg_list_add(zend_ast *list, zend_ast *arg)
|
||||
{
|
||||
if (list->kind == ZEND_AST_CALLABLE_CONVERT) {
|
||||
zend_ast_fcc *fcc_ast = (zend_ast_fcc*)list;
|
||||
fcc_ast->args = zend_ast_list_add(fcc_ast->args, arg);
|
||||
return (zend_ast*)fcc_ast;
|
||||
}
|
||||
|
||||
ZEND_ASSERT(list->kind == ZEND_AST_ARG_LIST);
|
||||
|
||||
if (zend_ast_is_placeholder_arg(arg)) {
|
||||
return zend_ast_create_fcc(zend_ast_list_add(list, arg));
|
||||
}
|
||||
|
||||
return zend_ast_list_add(list, arg);
|
||||
}
|
||||
|
||||
static zend_result zend_ast_add_array_element(const zval *result, zval *offset, zval *expr)
|
||||
{
|
||||
if (Z_TYPE_P(offset) == IS_UNDEF) {
|
||||
@@ -1060,6 +1143,15 @@ static zend_result ZEND_FASTCALL zend_ast_evaluate_inner(
|
||||
case ZEND_AST_CALL: {
|
||||
ZEND_ASSERT(ast->child[1]->kind == ZEND_AST_CALLABLE_CONVERT);
|
||||
zend_ast_fcc *fcc_ast = (zend_ast_fcc*)ast->child[1];
|
||||
|
||||
zend_ast_list *args = zend_ast_get_list(fcc_ast->args);
|
||||
ZEND_ASSERT(args->children > 0);
|
||||
if (args->children != 1 || args->child[0]->attr != ZEND_PLACEHOLDER_VARIADIC) {
|
||||
/* TODO: PFAs */
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Constant expression contains invalid operations");
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
fptr = ZEND_MAP_PTR_GET(fcc_ast->fptr);
|
||||
|
||||
if (!fptr) {
|
||||
@@ -1087,6 +1179,14 @@ static zend_result ZEND_FASTCALL zend_ast_evaluate_inner(
|
||||
ZEND_ASSERT(ast->child[2]->kind == ZEND_AST_CALLABLE_CONVERT);
|
||||
zend_ast_fcc *fcc_ast = (zend_ast_fcc*)ast->child[2];
|
||||
|
||||
zend_ast_list *args = zend_ast_get_list(fcc_ast->args);
|
||||
ZEND_ASSERT(args->children > 0);
|
||||
if (args->children != 1 || args->child[0]->attr != ZEND_PLACEHOLDER_VARIADIC) {
|
||||
/* TODO: PFAs */
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Constant expression contains invalid operations");
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
zend_class_entry *ce = zend_ast_fetch_class(ast->child[0], scope);
|
||||
if (!ce) {
|
||||
return FAILURE;
|
||||
@@ -1243,7 +1343,8 @@ static size_t ZEND_FASTCALL zend_ast_tree_size(zend_ast *ast)
|
||||
} else if (ast->kind == ZEND_AST_OP_ARRAY) {
|
||||
size = sizeof(zend_ast_op_array);
|
||||
} else if (ast->kind == ZEND_AST_CALLABLE_CONVERT) {
|
||||
size = sizeof(zend_ast_fcc);
|
||||
zend_ast *args_ast = ((zend_ast_fcc*)ast)->args;
|
||||
size = sizeof(zend_ast_fcc) + zend_ast_tree_size(args_ast);
|
||||
} else if (zend_ast_is_list(ast)) {
|
||||
uint32_t i;
|
||||
const zend_ast_list *list = zend_ast_get_list(ast);
|
||||
@@ -1320,6 +1421,8 @@ static void* ZEND_FASTCALL zend_ast_tree_copy(zend_ast *ast, void *buf)
|
||||
new->lineno = old->lineno;
|
||||
ZEND_MAP_PTR_INIT(new->fptr, ZEND_MAP_PTR(old->fptr));
|
||||
buf = (void*)((char*)buf + sizeof(zend_ast_fcc));
|
||||
new->args = buf;
|
||||
buf = zend_ast_tree_copy(old->args, buf);
|
||||
} else if (zend_ast_is_decl(ast)) {
|
||||
/* Not implemented. */
|
||||
ZEND_UNREACHABLE();
|
||||
@@ -1403,6 +1506,11 @@ tail_call:
|
||||
zend_ast_destroy(decl->child[3]);
|
||||
ast = decl->child[4];
|
||||
goto tail_call;
|
||||
} else if (EXPECTED(ast->kind == ZEND_AST_CALLABLE_CONVERT)) {
|
||||
zend_ast_fcc *fcc_ast = (zend_ast_fcc*) ast;
|
||||
|
||||
ast = fcc_ast->args;
|
||||
goto tail_call;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2299,6 +2407,13 @@ simple_list:
|
||||
EMPTY_SWITCH_DEFAULT_CASE();
|
||||
}
|
||||
break;
|
||||
case ZEND_AST_PLACEHOLDER_ARG:
|
||||
if (ast->attr == ZEND_PLACEHOLDER_VARIADIC) {
|
||||
APPEND_STR("...");
|
||||
} else {
|
||||
APPEND_STR("?");
|
||||
}
|
||||
break;
|
||||
|
||||
/* 1 child node */
|
||||
case ZEND_AST_VAR:
|
||||
@@ -2445,9 +2560,11 @@ simple_list:
|
||||
zend_ast_export_ex(str, ast->child[1], 0, indent);
|
||||
smart_str_appendc(str, ')');
|
||||
break;
|
||||
case ZEND_AST_CALLABLE_CONVERT:
|
||||
smart_str_appends(str, "...");
|
||||
break;
|
||||
case ZEND_AST_CALLABLE_CONVERT: {
|
||||
zend_ast_fcc *fcc_ast = (zend_ast_fcc*)ast;
|
||||
ast = fcc_ast->args;
|
||||
goto simple_list;
|
||||
}
|
||||
case ZEND_AST_CLASS_CONST:
|
||||
zend_ast_export_ns_name(str, ast->child[0], 0, indent);
|
||||
smart_str_appends(str, "::");
|
||||
|
||||
@@ -76,6 +76,7 @@ enum _zend_ast_kind {
|
||||
ZEND_AST_TYPE,
|
||||
ZEND_AST_CONSTANT_CLASS,
|
||||
ZEND_AST_CALLABLE_CONVERT,
|
||||
ZEND_AST_PLACEHOLDER_ARG,
|
||||
|
||||
/* 1 child node */
|
||||
ZEND_AST_VAR = 1 << ZEND_AST_NUM_CHILDREN_SHIFT,
|
||||
@@ -229,10 +230,12 @@ typedef struct _zend_ast_decl {
|
||||
zend_ast *child[5];
|
||||
} zend_ast_decl;
|
||||
|
||||
// TODO: rename
|
||||
typedef struct _zend_ast_fcc {
|
||||
zend_ast_kind kind; /* Type of the node (ZEND_AST_* enum constant) */
|
||||
zend_ast_attr attr; /* Additional attribute, use depending on node type */
|
||||
uint32_t lineno; /* Line number */
|
||||
zend_ast *args;
|
||||
ZEND_MAP_PTR_DEF(zend_function *, fptr);
|
||||
} zend_ast_fcc;
|
||||
|
||||
@@ -307,27 +310,39 @@ ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_0(zend_ast_kind kind);
|
||||
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_1(zend_ast_kind kind, zend_ast *child);
|
||||
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_2(zend_ast_kind kind, zend_ast *child1, zend_ast *child2);
|
||||
|
||||
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_arg_list_0(zend_ast_kind kind);
|
||||
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_arg_list_1(zend_ast_kind kind, zend_ast *child);
|
||||
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_arg_list_2(zend_ast_kind kind, zend_ast *child1, zend_ast *child2);
|
||||
|
||||
# define zend_ast_create(...) \
|
||||
ZEND_AST_SPEC_CALL(zend_ast_create, __VA_ARGS__)
|
||||
# define zend_ast_create_ex(...) \
|
||||
ZEND_AST_SPEC_CALL_EX(zend_ast_create_ex, __VA_ARGS__)
|
||||
# define zend_ast_create_list(init_children, ...) \
|
||||
ZEND_AST_SPEC_CALL(zend_ast_create_list, __VA_ARGS__)
|
||||
# define zend_ast_create_arg_list(init_children, ...) \
|
||||
ZEND_AST_SPEC_CALL(zend_ast_create_arg_list, __VA_ARGS__)
|
||||
|
||||
#else
|
||||
ZEND_API zend_ast *zend_ast_create(zend_ast_kind kind, ...);
|
||||
ZEND_API zend_ast *zend_ast_create_ex(zend_ast_kind kind, zend_ast_attr attr, ...);
|
||||
ZEND_API zend_ast *zend_ast_create_list(uint32_t init_children, zend_ast_kind kind, ...);
|
||||
ZEND_API zend_ast *zend_ast_create_arg_list(uint32_t init_children, zend_ast_kind kind, ...);
|
||||
#endif
|
||||
|
||||
ZEND_ATTRIBUTE_NODISCARD ZEND_API zend_ast * ZEND_FASTCALL zend_ast_list_add(zend_ast *list, zend_ast *op);
|
||||
|
||||
/* Like zend_ast_list_add(), but wraps the list into a ZEND_AST_CALLABLE_CONVERT
|
||||
* if any arg is a ZEND_AST_PLACEHOLDER_ARG. list can be a zend_ast_list, or a
|
||||
* zend_ast_fcc. */
|
||||
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_arg_list_add(zend_ast *list, zend_ast *arg);
|
||||
|
||||
ZEND_API zend_ast *zend_ast_create_decl(
|
||||
zend_ast_kind kind, uint32_t flags, uint32_t start_lineno, zend_string *doc_comment,
|
||||
zend_string *name, zend_ast *child0, zend_ast *child1, zend_ast *child2, zend_ast *child3, zend_ast *child4
|
||||
);
|
||||
|
||||
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_fcc(void);
|
||||
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_fcc(zend_ast *args);
|
||||
|
||||
typedef struct {
|
||||
bool had_side_effects;
|
||||
|
||||
@@ -3948,6 +3948,11 @@ static bool zend_compile_call_common(znode *result, zend_ast *args_ast, const ze
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Cannot create Closure for new expression");
|
||||
}
|
||||
|
||||
zend_ast_list *args = zend_ast_get_list(((zend_ast_fcc*)args_ast)->args);
|
||||
if (args->children != 1 || args->child[0]->attr != ZEND_PLACEHOLDER_VARIADIC) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Cannot create a Closure for call expression with more than one argument, or non-variadic placeholders");
|
||||
}
|
||||
|
||||
if (opcode == ZEND_INIT_FCALL) {
|
||||
opline->op1.num = zend_vm_calc_used_stack(0, fbc);
|
||||
}
|
||||
|
||||
@@ -1236,6 +1236,9 @@ static zend_always_inline bool zend_check_arg_send_type(const zend_function *zf,
|
||||
#define ZEND_IS_BINARY_ASSIGN_OP_OPCODE(opcode) \
|
||||
(((opcode) >= ZEND_ADD) && ((opcode) <= ZEND_POW))
|
||||
|
||||
/* PFAs/FCCs */
|
||||
#define ZEND_PLACEHOLDER_VARIADIC (1<<0)
|
||||
|
||||
/* Pseudo-opcodes that are used only temporarily during compilation */
|
||||
#define ZEND_GOTO 253
|
||||
#define ZEND_BRK 254
|
||||
|
||||
@@ -901,16 +901,15 @@ return_type:
|
||||
;
|
||||
|
||||
argument_list:
|
||||
'(' ')' { $$ = zend_ast_create_list(0, ZEND_AST_ARG_LIST); }
|
||||
'(' ')' { $$ = zend_ast_create_arg_list(0, ZEND_AST_ARG_LIST); }
|
||||
| '(' non_empty_argument_list possible_comma ')' { $$ = $2; }
|
||||
| '(' T_ELLIPSIS ')' { $$ = zend_ast_create_fcc(); }
|
||||
;
|
||||
|
||||
non_empty_argument_list:
|
||||
argument
|
||||
{ $$ = zend_ast_create_list(1, ZEND_AST_ARG_LIST, $1); }
|
||||
{ $$ = zend_ast_create_arg_list(1, ZEND_AST_ARG_LIST, $1); }
|
||||
| non_empty_argument_list ',' argument
|
||||
{ $$ = zend_ast_list_add($1, $3); }
|
||||
{ $$ = zend_ast_arg_list_add($1, $3); }
|
||||
;
|
||||
|
||||
/* `clone_argument_list` is necessary to resolve a parser ambiguity (shift-reduce conflict)
|
||||
@@ -923,25 +922,31 @@ non_empty_argument_list:
|
||||
* syntax.
|
||||
*/
|
||||
clone_argument_list:
|
||||
'(' ')' { $$ = zend_ast_create_list(0, ZEND_AST_ARG_LIST); }
|
||||
'(' ')' { $$ = zend_ast_create_arg_list(0, ZEND_AST_ARG_LIST); }
|
||||
| '(' non_empty_clone_argument_list possible_comma ')' { $$ = $2; }
|
||||
| '(' expr ',' ')' { $$ = zend_ast_create_list(1, ZEND_AST_ARG_LIST, $2); }
|
||||
| '(' T_ELLIPSIS ')' { $$ = zend_ast_create_fcc(); }
|
||||
| '(' expr ',' ')' { $$ = zend_ast_create_arg_list(1, ZEND_AST_ARG_LIST, $2); }
|
||||
;
|
||||
|
||||
non_empty_clone_argument_list:
|
||||
expr ',' argument
|
||||
{ $$ = zend_ast_create_list(2, ZEND_AST_ARG_LIST, $1, $3); }
|
||||
{ $$ = zend_ast_create_arg_list(2, ZEND_AST_ARG_LIST, $1, $3); }
|
||||
| argument_no_expr
|
||||
{ $$ = zend_ast_create_list(1, ZEND_AST_ARG_LIST, $1); }
|
||||
{ $$ = zend_ast_create_arg_list(1, ZEND_AST_ARG_LIST, $1); }
|
||||
| non_empty_clone_argument_list ',' argument
|
||||
{ $$ = zend_ast_list_add($1, $3); }
|
||||
{ $$ = zend_ast_arg_list_add($1, $3); }
|
||||
;
|
||||
|
||||
argument_no_expr:
|
||||
identifier ':' expr
|
||||
{ $$ = zend_ast_create(ZEND_AST_NAMED_ARG, $1, $3); }
|
||||
| T_ELLIPSIS expr { $$ = zend_ast_create(ZEND_AST_UNPACK, $2); }
|
||||
| T_ELLIPSIS
|
||||
{ $$ = zend_ast_create_ex(ZEND_AST_PLACEHOLDER_ARG, ZEND_PLACEHOLDER_VARIADIC); }
|
||||
| '?'
|
||||
{ $$ = zend_ast_create(ZEND_AST_PLACEHOLDER_ARG); }
|
||||
| identifier ':' '?'
|
||||
{ $$ = zend_ast_create(ZEND_AST_NAMED_ARG, $1, zend_ast_create(ZEND_AST_PLACEHOLDER_ARG)); }
|
||||
| T_ELLIPSIS expr
|
||||
{ $$ = zend_ast_create(ZEND_AST_UNPACK, $2); }
|
||||
;
|
||||
|
||||
argument:
|
||||
|
||||
@@ -638,6 +638,9 @@ struct _zend_ast_ref {
|
||||
#define _IS_BOOL 18
|
||||
#define _IS_NUMBER 19
|
||||
|
||||
/* used for PFAs/FCCs */
|
||||
#define _IS_PLACEHOLDER 20
|
||||
|
||||
/* guard flags */
|
||||
#define ZEND_GUARD_PROPERTY_GET (1<<0)
|
||||
#define ZEND_GUARD_PROPERTY_SET (1<<1)
|
||||
|
||||
@@ -384,6 +384,7 @@ static void zend_file_cache_serialize_ast(zend_ast *ast,
|
||||
} else if (ast->kind == ZEND_AST_CALLABLE_CONVERT) {
|
||||
zend_ast_fcc *fcc = (zend_ast_fcc*)ast;
|
||||
ZEND_MAP_PTR_INIT(fcc->fptr, NULL);
|
||||
zend_file_cache_serialize_ast(fcc->args, script, info, buf);
|
||||
} else if (zend_ast_is_decl(ast)) {
|
||||
/* Not implemented. */
|
||||
ZEND_UNREACHABLE();
|
||||
@@ -1304,6 +1305,7 @@ static void zend_file_cache_unserialize_ast(zend_ast *ast,
|
||||
} else if (ast->kind == ZEND_AST_CALLABLE_CONVERT) {
|
||||
zend_ast_fcc *fcc = (zend_ast_fcc*)ast;
|
||||
ZEND_MAP_PTR_NEW(fcc->fptr);
|
||||
zend_file_cache_unserialize_ast(fcc->args, script, buf);
|
||||
} else if (zend_ast_is_decl(ast)) {
|
||||
/* Not implemented. */
|
||||
ZEND_UNREACHABLE();
|
||||
@@ -2109,7 +2111,7 @@ void zend_file_cache_invalidate(zend_string *full_path)
|
||||
if (ZCG(accel_directives).file_cache_read_only) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
char *filename;
|
||||
|
||||
filename = zend_file_cache_get_bin_file_path(full_path);
|
||||
|
||||
@@ -197,6 +197,7 @@ static zend_ast *zend_persist_ast(zend_ast *ast)
|
||||
node = (zend_ast *) copy;
|
||||
} else if (ast->kind == ZEND_AST_CALLABLE_CONVERT) {
|
||||
zend_ast_fcc *copy = zend_shared_memdup(ast, sizeof(zend_ast_fcc));
|
||||
copy->args = zend_persist_ast(copy->args);
|
||||
node = (zend_ast *) copy;
|
||||
} else if (zend_ast_is_decl(ast)) {
|
||||
/* Not implemented. */
|
||||
|
||||
@@ -92,7 +92,9 @@ static void zend_persist_ast_calc(zend_ast *ast)
|
||||
ZVAL_PTR(&z, zend_ast_get_op_array(ast)->op_array);
|
||||
zend_persist_op_array_calc(&z);
|
||||
} else if (ast->kind == ZEND_AST_CALLABLE_CONVERT) {
|
||||
zend_ast_fcc *fcc_ast = (zend_ast_fcc*)ast;
|
||||
ADD_SIZE(sizeof(zend_ast_fcc));
|
||||
zend_persist_ast_calc(fcc_ast->args);
|
||||
} else if (zend_ast_is_decl(ast)) {
|
||||
/* Not implemented. */
|
||||
ZEND_UNREACHABLE();
|
||||
|
||||
Reference in New Issue
Block a user