Skip to content

Commit 46320ec

Browse files
author
rjhdby
committed
parent call
1 parent fc5fdf7 commit 46320ec

File tree

3 files changed

+117
-44
lines changed

3 files changed

+117
-44
lines changed

Zend/zend_ast.c

Lines changed: 89 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -396,47 +396,6 @@ ZEND_API zend_ast * ZEND_FASTCALL zend_ast_list_add(zend_ast *ast, zend_ast *op)
396396
return (zend_ast *) list;
397397
}
398398

399-
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_add_constructor(zend_ast *ast, uint32_t start_lineno, zend_ast *params) {
400-
zend_ast_list* par_list = (zend_ast_list *) params;
401-
int i;
402-
zend_ast* body_ast = zend_ast_create_list(0, ZEND_AST_STMT_LIST);
403-
404-
for(i=0; i < par_list->children; i++){
405-
zval *param = zend_ast_get_zval(par_list->child[i]->child[1]);
406-
char* param_name = Z_STRVAL_P(param);
407-
408-
zend_ast *class_prop = zend_ast_create(
409-
ZEND_AST_PROP,
410-
zend_ast_create(
411-
ZEND_AST_VAR,
412-
zend_ast_create_zval_from_str(zend_string_init("this", strlen("this"), 0))
413-
),
414-
zend_ast_create_zval_from_str(zend_string_init(param_name, strlen(param_name), 0))
415-
);
416-
417-
zend_ast *constructor_param = zend_ast_create(
418-
ZEND_AST_VAR,
419-
zend_ast_create_zval_from_str(zend_string_init(param_name, strlen(param_name), 0))
420-
);
421-
422-
zend_ast *assignment = zend_ast_create(ZEND_AST_ASSIGN, class_prop, constructor_param);
423-
zend_ast_list_add(body_ast, assignment);
424-
}
425-
426-
zend_ast *constructor = zend_ast_create_decl(
427-
ZEND_AST_METHOD,
428-
ZEND_ACC_PUBLIC,
429-
start_lineno,
430-
NULL,
431-
zend_string_init("__construct", strlen("__construct"), 0),
432-
params,
433-
NULL,
434-
body_ast,
435-
NULL
436-
);
437-
return zend_ast_list_add(ast, constructor);
438-
}
439-
440399
static int zend_ast_add_array_element(zval *result, zval *offset, zval *expr)
441400
{
442401
switch (Z_TYPE_P(offset)) {
@@ -2038,6 +1997,95 @@ ZEND_API ZEND_COLD zend_string *zend_ast_export(const char *prefix, zend_ast *as
20381997
return str.s;
20391998
}
20401999

2000+
/*
2001+
* ast_inject
2002+
*/
2003+
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_inj_create_method(char* name, uint32_t start_lineno, zend_ast_attr attr, zend_ast *params, zend_ast *body) {
2004+
return zend_ast_create_decl(
2005+
ZEND_AST_METHOD,
2006+
attr,
2007+
start_lineno,
2008+
NULL,
2009+
CHAR_TO_ZEND_STR(name),
2010+
params,
2011+
NULL,
2012+
body,
2013+
NULL
2014+
);
2015+
}
2016+
2017+
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_inj_this_var(char *name) {
2018+
return zend_ast_create(
2019+
ZEND_AST_PROP,
2020+
zend_ast_create(
2021+
ZEND_AST_VAR,
2022+
zend_ast_create_zval_from_str(CHAR_TO_ZEND_STR("this"))
2023+
),
2024+
zend_ast_create_zval_from_str(CHAR_TO_ZEND_STR(name))
2025+
);
2026+
}
2027+
2028+
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_inj_create_property_decl(char *name, zval* value) {
2029+
return zend_ast_create(
2030+
ZEND_AST_PROP_ELEM,
2031+
zend_ast_create_zval_from_str(CHAR_TO_ZEND_STR(name)),
2032+
value ? zend_ast_create_zval(value) : NULL,
2033+
NULL
2034+
);
2035+
}
2036+
2037+
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_inj_var(char *name) {
2038+
return zend_ast_create(
2039+
ZEND_AST_VAR,
2040+
zend_ast_create_zval_from_str(CHAR_TO_ZEND_STR(name))
2041+
);
2042+
}
2043+
2044+
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_inj_add_cf_construct(zend_ast *ast, uint32_t start_lineno, zend_ast *params, zend_ast *parent_arguments) {
2045+
int i;
2046+
zend_ast* body_ast = zend_ast_create_list(0, ZEND_AST_STMT_LIST);
2047+
zend_ast* properties_ast = zend_ast_create_list(0, ZEND_AST_PROP_DECL);
2048+
2049+
if(parent_arguments){
2050+
zend_ast *parent = zend_ast_create_zval_from_str(CHAR_TO_ZEND_STR("parent"));
2051+
parent->attr = ZEND_NAME_NOT_FQ;
2052+
zend_ast *call = zend_ast_create(
2053+
ZEND_AST_STATIC_CALL,
2054+
parent,
2055+
zend_ast_create_zval_from_str(CHAR_TO_ZEND_STR(ZEND_CONSTRUCTOR_FUNC_NAME)),
2056+
parent_arguments
2057+
);
2058+
2059+
zend_ast_list_add(body_ast, call);
2060+
}
2061+
2062+
for(i=0; i < ZEND_AST_CHILD_COUNT(params); i++){
2063+
zend_ast *class_prop = zend_ast_inj_this_var(ZEND_AST_PARAM_NAME(params, i));
2064+
zend_ast *constructor_param = ZEND_AST_PARAM_AS_VAR(params, i);
2065+
zend_ast *prop_declaration = zend_ast_inj_create_property_decl(ZEND_AST_PARAM_NAME(params, i), NULL);
2066+
2067+
zend_ast_list_add(properties_ast, prop_declaration);
2068+
zend_ast_list_add(body_ast, zend_ast_create(ZEND_AST_ASSIGN, class_prop, constructor_param));
2069+
}
2070+
2071+
if(ZEND_AST_CHILD_COUNT(properties_ast)){
2072+
properties_ast->attr = ZEND_ACC_PUBLIC;
2073+
zend_ast_list_add(ast, properties_ast);
2074+
}
2075+
2076+
zend_ast *constructor = zend_ast_inj_create_method(
2077+
ZEND_CONSTRUCTOR_FUNC_NAME,
2078+
start_lineno,
2079+
ZEND_ACC_PUBLIC,
2080+
params,
2081+
body_ast
2082+
);
2083+
return zend_ast_list_add(ast, constructor);
2084+
}
2085+
/*
2086+
* ast_inject end
2087+
*/
2088+
20412089
/*
20422090
* Local variables:
20432091
* tab-width: 4

Zend/zend_ast.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,6 @@ ZEND_API zend_ast *zend_ast_create_list(uint32_t init_children, zend_ast_kind ki
261261
#endif
262262

263263
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_list_add(zend_ast *list, zend_ast *op);
264-
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_add_constructor(zend_ast *ast, uint32_t start_lineno, zend_ast *params);
265264

266265
ZEND_API zend_ast *zend_ast_create_decl(
267266
zend_ast_kind kind, uint32_t flags, uint32_t start_lineno, zend_string *doc_comment,
@@ -331,6 +330,23 @@ static zend_always_inline zend_ast *zend_ast_list_rtrim(zend_ast *ast) {
331330
}
332331
return ast;
333332
}
333+
/*
334+
* ast_inject
335+
*/
336+
337+
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_inj_create_method(char* name, uint32_t start_lineno, zend_ast_attr attr, zend_ast *params, zend_ast *body);
338+
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_inj_this_var(char *name);
339+
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_inj_var(char *name);
340+
341+
#define CHAR_TO_ZEND_STR(value) zend_string_init(value, strlen(value), 0)
342+
#define ZEND_AST_PARAM_NAME(params, index) Z_STRVAL_P(zend_ast_get_zval(((zend_ast_list *) params)->child[index]->child[1]))
343+
#define ZEND_AST_CHILD_COUNT(params) ((zend_ast_list *) params)->children
344+
#define ZEND_AST_PARAM_AS_VAR(params, index) zend_ast_inj_var(Z_STRVAL_P(zend_ast_get_zval(((zend_ast_list *) params)->child[index]->child[1])))
345+
346+
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_inj_add_cf_construct(zend_ast *ast, uint32_t start_lineno, zend_ast *params, zend_ast *parent_arguments);
347+
/*
348+
* ast_inject end
349+
*/
334350
#endif
335351

336352
/*

Zend/zend_language_parser.y

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
232232
%type <ast> unprefixed_use_declarations const_decl inner_statement
233233
%type <ast> expr optional_expr while_statement for_statement foreach_variable
234234
%type <ast> foreach_statement declare_statement finally_statement unset_variable variable
235-
%type <ast> extends_from parameter optional_type argument global_var
235+
%type <ast> extends_from not_empty_extends_from parameter optional_type argument global_var
236236
%type <ast> static_var class_statement trait_adaptation trait_precedence trait_alias
237237
%type <ast> absolute_trait_method_reference trait_method_reference property echo_expr
238238
%type <ast> new_expr anonymous_class class_name class_name_reference simple_variable
@@ -509,7 +509,12 @@ class_declaration_statement:
509509
| T_CLASS
510510
T_STRING '(' parameter_list ')' extends_from implements_list backup_doc_comment '{' class_statement_list '}'
511511
{ $$ = zend_ast_create_decl(ZEND_AST_CLASS, 0, CG(zend_lineno), $8, zend_ast_get_str($2), $6,
512-
$7, zend_ast_add_constructor($10, CG(zend_lineno), $4), NULL);
512+
$7, zend_ast_inj_add_cf_construct($10, CG(zend_lineno), $4, NULL), NULL);
513+
}
514+
| T_CLASS
515+
T_STRING '(' parameter_list ')' not_empty_extends_from argument_list implements_list backup_doc_comment '{' class_statement_list '}'
516+
{ $$ = zend_ast_create_decl(ZEND_AST_CLASS, 0, CG(zend_lineno), $9, zend_ast_get_str($2), $6,
517+
$8, zend_ast_inj_add_cf_construct($11, CG(zend_lineno), $4, $7), NULL);
513518
}
514519
;
515520

@@ -541,6 +546,10 @@ extends_from:
541546
| T_EXTENDS name { $$ = $2; }
542547
;
543548

549+
not_empty_extends_from:
550+
T_EXTENDS name { $$ = $2; }
551+
;
552+
544553
interface_extends_list:
545554
/* empty */ { $$ = NULL; }
546555
| T_EXTENDS name_list { $$ = $2; }

0 commit comments

Comments
 (0)