return (zend_ast *) ast;
}
-ZEND_API zend_ast *zend_ast_create_func_decl(
+ZEND_API zend_ast *zend_ast_create_decl(
zend_ast_kind kind, zend_uint flags, zend_uint start_lineno, zend_uint end_lineno,
unsigned char *lex_pos, zend_string *doc_comment, zend_string *name,
- zend_ast *params, zend_ast *uses, zend_ast *stmt
+ zend_ast *child0, zend_ast *child1, zend_ast *child2
) {
- zend_ast_func_decl *ast = emalloc(sizeof(zend_ast_func_decl));
+ zend_ast_decl *ast = emalloc(sizeof(zend_ast_decl));
ast->kind = kind;
ast->attr = 0;
ast->lex_pos = lex_pos;
ast->doc_comment = doc_comment;
ast->name = name;
- ast->params = params;
- ast->uses = uses;
- ast->stmt = stmt;
+ ast->child[0] = child0;
+ ast->child[1] = child1;
+ ast->child[2] = child2;
return (zend_ast *) ast;
}
case ZEND_AST_CLOSURE:
case ZEND_AST_METHOD:
{
- zend_ast_func_decl *fn = (zend_ast_func_decl *) ast;
- STR_RELEASE(fn->name);
- if (fn->doc_comment) {
- STR_RELEASE(fn->doc_comment);
+ zend_ast_decl *decl = (zend_ast_decl *) ast;
+ STR_RELEASE(decl->name);
+ if (decl->doc_comment) {
+ STR_RELEASE(decl->doc_comment);
}
- zend_ast_destroy(fn->params);
- zend_ast_destroy(fn->uses);
- zend_ast_destroy(fn->stmt);
+ zend_ast_destroy(decl->child[0]);
+ zend_ast_destroy(decl->child[1]);
+ zend_ast_destroy(decl->child[2]);
break;
}
default:
zval val;
} zend_ast_zval;
-/* Using a separate structure as it needs a bunch of extra information. */
-typedef struct _zend_ast_func_decl {
+/* Separate structure for function and class declaration, as they need extra information. */
+typedef struct _zend_ast_decl {
zend_ast_kind kind;
zend_ast_attr attr; /* Unused - for structure compatibility */
zend_uint start_lineno;
unsigned char *lex_pos;
zend_string *doc_comment;
zend_string *name;
- zend_ast *params;
- zend_ast *uses;
- zend_ast *stmt;
-} zend_ast_func_decl;
+ zend_ast *child[3];
+} zend_ast_decl;
static inline zval *zend_ast_get_zval(zend_ast *ast) {
return &((zend_ast_zval *) ast)->val;
ZEND_API zend_ast *zend_ast_create(
zend_uint children, zend_ast_kind kind, ...);
-ZEND_API zend_ast *zend_ast_create_func_decl(
+ZEND_API zend_ast *zend_ast_create_decl(
zend_ast_kind kind, zend_uint flags, zend_uint start_lineno, zend_uint end_lineno,
unsigned char *lex_pos, zend_string *doc_comment, zend_string *name,
- zend_ast *params, zend_ast *uses, zend_ast *stmt
+ zend_ast *child0, zend_ast *child1, zend_ast *child2
);
ZEND_API zend_ast *zend_ast_create_dynamic(zend_ast_kind kind);
}
static void zend_begin_func_decl(
- znode *result, zend_op_array *op_array, zend_ast_func_decl *fn TSRMLS_DC
+ znode *result, zend_op_array *op_array, zend_ast_decl *decl TSRMLS_DC
) {
- zend_string *name = fn->name, *lcname;
+ zend_ast *params_ast = decl->child[0];
+ zend_string *name = decl->name, *lcname;
zend_op *opline;
if (Z_TYPE(CG(current_namespace)) != IS_UNDEF) {
}
}
- if (zend_str_equals(lcname, ZEND_AUTOLOAD_FUNC_NAME) && fn->params->children != 1) {
+ if (zend_str_equals(lcname, ZEND_AUTOLOAD_FUNC_NAME) && params_ast->children != 1) {
zend_error_noreturn(E_COMPILE_ERROR, "%s() must take exactly 1 argument",
ZEND_AUTOLOAD_FUNC_NAME);
}
{
zval key;
- build_runtime_defined_function_key(&key, lcname, fn->lex_pos TSRMLS_CC);
+ build_runtime_defined_function_key(&key, lcname, decl->lex_pos TSRMLS_CC);
opline->op1_type = IS_CONST;
opline->op1.constant = zend_add_literal(CG(active_op_array), &key TSRMLS_CC);
}
void zend_compile_func_decl(znode *result, zend_ast *ast TSRMLS_DC) {
- zend_ast_func_decl *fn = (zend_ast_func_decl *) ast;
+ zend_ast_decl *decl = (zend_ast_decl *) ast;
+ zend_ast *params_ast = decl->child[0];
+ zend_ast *uses_ast = decl->child[1];
+ zend_ast *stmt_ast = decl->child[2];
+ zend_bool is_method = decl->kind == ZEND_AST_METHOD;
+
zend_op_array *orig_op_array = CG(active_op_array);
zend_op_array *op_array = emalloc(sizeof(zend_op_array));
- zend_bool is_method = ast->kind == ZEND_AST_METHOD;
// TODO.AST interactive (not just here - also bpc etc!)
init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
- op_array->fn_flags |= fn->flags;
- op_array->line_start = fn->start_lineno;
- op_array->line_end = fn->end_lineno;
- if (fn->doc_comment) {
- op_array->doc_comment = STR_COPY(fn->doc_comment);
+ op_array->fn_flags |= decl->flags;
+ op_array->line_start = decl->start_lineno;
+ op_array->line_end = decl->end_lineno;
+ if (decl->doc_comment) {
+ op_array->doc_comment = STR_COPY(decl->doc_comment);
}
- if (ast->kind == ZEND_AST_CLOSURE) {
+ if (decl->kind == ZEND_AST_CLOSURE) {
op_array->fn_flags |= ZEND_ACC_CLOSURE;
}
if (is_method) {
- zend_bool has_body = fn->stmt != NULL;
- zend_begin_method_decl(op_array, fn->name, has_body TSRMLS_CC);
+ zend_bool has_body = stmt_ast != NULL;
+ zend_begin_method_decl(op_array, decl->name, has_body TSRMLS_CC);
} else {
- zend_begin_func_decl(result, op_array, fn TSRMLS_CC);
+ zend_begin_func_decl(result, op_array, decl TSRMLS_CC);
}
CG(active_op_array) = op_array;
if (CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO) {
zend_op *opline_ext = emit_op(NULL, ZEND_EXT_NOP, NULL, NULL TSRMLS_CC);
- opline_ext->lineno = fn->start_lineno;
+ opline_ext->lineno = decl->start_lineno;
}
{
zend_stack_push(&CG(foreach_copy_stack), (void *) &dummy_opline);
}
- zend_compile_params(fn->params TSRMLS_CC);
- zend_compile_closure_uses(fn->uses TSRMLS_CC);
- zend_compile_stmt(fn->stmt TSRMLS_CC);
+ zend_compile_params(params_ast TSRMLS_CC);
+ zend_compile_closure_uses(uses_ast TSRMLS_CC);
+ zend_compile_stmt(stmt_ast TSRMLS_CC);
if (is_method) {
zend_check_magic_method_implementation(
function_declaration_statement:
function returns_ref T_STRING '(' parameter_list ')' '{' inner_statement_list '}'
- { $$.u.ast = zend_ast_create_func_decl(ZEND_AST_FUNC_DECL, $2.EA,
+ { $$.u.ast = zend_ast_create_decl(ZEND_AST_FUNC_DECL, $2.EA,
$1.EA, CG(zend_lineno), LANG_SCNG(yy_text), $1.u.op.ptr,
Z_STR($3.u.constant), $5.u.ast, NULL, $8.u.ast); }
;
| T_USE name_list trait_adaptations
{ $$.u.ast = zend_ast_create_binary(ZEND_AST_USE_TRAIT, $2.u.ast, $3.u.ast); AS($$); }
| method_modifiers function returns_ref T_STRING '(' parameter_list ')' method_body
- { $$.u.ast = zend_ast_create_func_decl(ZEND_AST_METHOD, $3.EA | Z_LVAL($1.u.constant),
+ { $$.u.ast = zend_ast_create_decl(ZEND_AST_METHOD, $3.EA | Z_LVAL($1.u.constant),
$2.EA, CG(zend_lineno), LANG_SCNG(yy_text), $2.u.op.ptr,
Z_STR($4.u.constant), $6.u.ast, NULL, $8.u.ast); AS($$); }
;
| T_YIELD expr T_DOUBLE_ARROW expr
{ $$.u.ast = zend_ast_create_binary(ZEND_YIELD, $4.u.ast, $2.u.ast); }
| function returns_ref '(' parameter_list ')' lexical_vars '{' inner_statement_list '}'
- { $$.u.ast = zend_ast_create_func_decl(ZEND_AST_CLOSURE, $2.EA,
+ { $$.u.ast = zend_ast_create_decl(ZEND_AST_CLOSURE, $2.EA,
$1.EA, CG(zend_lineno), LANG_SCNG(yy_text), $1.u.op.ptr,
STR_INIT("{closure}", sizeof("{closure}") - 1, 0),
$4.u.ast, $6.u.ast, $8.u.ast); }
| T_STATIC function returns_ref '(' parameter_list ')' lexical_vars
'{' inner_statement_list '}'
- { $$.u.ast = zend_ast_create_func_decl(ZEND_AST_CLOSURE,
+ { $$.u.ast = zend_ast_create_decl(ZEND_AST_CLOSURE,
$3.EA | ZEND_ACC_STATIC, $2.EA, CG(zend_lineno), LANG_SCNG(yy_text),
$2.u.op.ptr, STR_INIT("{closure}", sizeof("{closure}") - 1, 0),
$5.u.ast, $7.u.ast, $9.u.ast); }