Skip to content

Commit 66b77d6

Browse files
committed
Applied @bwoebi's grammar patch to enable T_DEFAULT in expressions.
Patched match expression to work with the new grammar. Changed ZEND_FETCH_DEFAULT_ARG VM handler to use reflection_parameter_ptr.
1 parent d33f2cb commit 66b77d6

10 files changed

+49
-39
lines changed

Zend/tests/default_expression/global user function.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
--TEST--
2-
Test passing default argument to global user function.
2+
Tests passing default to a global user function parameter
33
--FILE--
44
<?php
55

Zend/tests/default_expression/multiple arguments.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
--TEST--
2-
Test passing multiple default arguments to global user function.
2+
Test passing multiple default arguments to global user function parameters
33
--FILE--
44
<?php
55

Zend/tests/default_expression/user class method.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
--TEST--
2-
Test passing default argument to user class method.
2+
Tests passing default to a user class method parameter
33
--FILE--
44
<?php
55

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--TEST--
2+
Tests passing default to a user class static method parameter
3+
--FILE--
4+
<?php
5+
6+
class C {
7+
static function F($V = 'Alfa') {
8+
var_dump($V);
9+
}
10+
}
11+
C::f(default);
12+
?>
13+
--EXPECT--
14+
string(4) "Alfa"

Zend/zend_ast.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2013,6 +2013,9 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio
20132013
EMPTY_SWITCH_DEFAULT_CASE();
20142014
}
20152015
break;
2016+
case ZEND_AST_DEFAULT:
2017+
smart_str_appends(str, "default");
2018+
break;
20162019

20172020
/* 1 child node */
20182021
case ZEND_AST_VAR:

Zend/zend_compile.c

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6358,11 +6358,12 @@ static uint32_t count_match_conds(zend_ast_list *arms)
63586358

63596359
for (uint32_t i = 0; i < arms->children; i++) {
63606360
zend_ast *arm_ast = arms->child[i];
6361-
if (arm_ast->child[0] == NULL) {
6361+
zend_ast_list *conds = zend_ast_get_list(arm_ast->child[0]);
6362+
6363+
if (conds->child[0]->kind == ZEND_AST_DEFAULT) {
63626364
continue;
63636365
}
63646366

6365-
zend_ast_list *conds = zend_ast_get_list(arm_ast->child[0]);
63666367
num_conds += conds->children;
63676368
}
63686369

@@ -6372,12 +6373,13 @@ static uint32_t count_match_conds(zend_ast_list *arms)
63726373
static bool can_match_use_jumptable(zend_ast_list *arms) {
63736374
for (uint32_t i = 0; i < arms->children; i++) {
63746375
zend_ast *arm_ast = arms->child[i];
6375-
if (!arm_ast->child[0]) {
6376+
zend_ast_list *conds = zend_ast_get_list(arm_ast->child[0]);
6377+
6378+
if (conds->child[0]->kind == ZEND_AST_DEFAULT) {
63766379
/* Skip default arm */
63776380
continue;
63786381
}
63796382

6380-
zend_ast_list *conds = zend_ast_get_list(arm_ast->child[0]);
63816383
for (uint32_t j = 0; j < conds->children; j++) {
63826384
zend_ast **cond_ast = &conds->child[j];
63836385

@@ -6418,8 +6420,9 @@ static void zend_compile_match(znode *result, zend_ast *ast)
64186420

64196421
for (uint32_t i = 0; i < arms->children; ++i) {
64206422
zend_ast *arm_ast = arms->child[i];
6423+
zend_ast_list *conds = zend_ast_get_list(arm_ast->child[0]);
64216424

6422-
if (!arm_ast->child[0]) {
6425+
if (conds->child[0]->kind == ZEND_AST_DEFAULT) {
64236426
if (has_default_arm) {
64246427
CG(zend_lineno) = arm_ast->lineno;
64256428
zend_error_noreturn(E_COMPILE_ERROR,
@@ -6447,15 +6450,15 @@ static void zend_compile_match(znode *result, zend_ast *ast)
64476450
uint32_t cond_count = 0;
64486451
for (uint32_t i = 0; i < arms->children; ++i) {
64496452
zend_ast *arm_ast = arms->child[i];
6450-
6451-
if (!arm_ast->child[0]) {
6452-
continue;
6453-
}
6454-
64556453
zend_ast_list *conds = zend_ast_get_list(arm_ast->child[0]);
6454+
64566455
for (uint32_t j = 0; j < conds->children; j++) {
64576456
zend_ast *cond_ast = conds->child[j];
64586457

6458+
if (conds->child[0]->kind == ZEND_AST_DEFAULT) {
6459+
break;
6460+
}
6461+
64596462
znode cond_node;
64606463
zend_compile_expr(&cond_node, cond_ast);
64616464

@@ -6507,10 +6510,9 @@ static void zend_compile_match(znode *result, zend_ast *ast)
65076510
for (uint32_t i = 0; i < arms->children; ++i) {
65086511
zend_ast *arm_ast = arms->child[i];
65096512
zend_ast *body_ast = arm_ast->child[1];
6513+
zend_ast_list *conds = zend_ast_get_list(arm_ast->child[0]);
65106514

6511-
if (arm_ast->child[0] != NULL) {
6512-
zend_ast_list *conds = zend_ast_get_list(arm_ast->child[0]);
6513-
6515+
if (conds->child[0]->kind != ZEND_AST_DEFAULT) {
65146516
for (uint32_t j = 0; j < conds->children; j++) {
65156517
zend_ast *cond_ast = conds->child[j];
65166518

Zend/zend_execute.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include "zend_system_id.h"
4545
#include "zend_call_stack.h"
4646
#include "zend_attributes.h"
47+
#include "ext/reflection/php_reflection.h"
4748
#include "Optimizer/zend_func_info.h"
4849

4950
/* Virtual current working directory support */

Zend/zend_language_parser.y

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
8686
%precedence T_ELSEIF
8787
%precedence T_ELSE
8888

89+
%precedence T_DEFAULT
90+
%precedence T_SWITCH_DEFAULT
91+
8992
%token <ast> T_LNUMBER "integer"
9093
%token <ast> T_DNUMBER "floating-point number"
9194
%token <ast> T_STRING "identifier"
@@ -251,7 +254,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
251254
%type <ast> group_use_declaration inline_use_declarations inline_use_declaration
252255
%type <ast> mixed_group_use_declaration use_declaration unprefixed_use_declaration
253256
%type <ast> unprefixed_use_declarations const_decl inner_statement
254-
%type <ast> expr expr_with_default optional_expr while_statement for_statement foreach_variable
257+
%type <ast> expr optional_expr while_statement for_statement foreach_variable
255258
%type <ast> foreach_statement declare_statement finally_statement unset_variable variable
256259
%type <ast> extends_from parameter optional_type_without_static argument global_var
257260
%type <ast> static_var class_statement trait_adaptation trait_precedence trait_alias
@@ -702,9 +705,9 @@ switch_case_list:
702705

703706
case_list:
704707
%empty { $$ = zend_ast_create_list(0, ZEND_AST_SWITCH_LIST); }
705-
| case_list T_CASE expr case_separator inner_statement_list
708+
| case_list T_CASE expr case_separator inner_statement_list %prec T_SWITCH_DEFAULT
706709
{ $$ = zend_ast_list_add($1, zend_ast_create(ZEND_AST_SWITCH_CASE, $3, $5)); }
707-
| case_list T_DEFAULT case_separator inner_statement_list
710+
| case_list T_DEFAULT case_separator inner_statement_list %prec T_SWITCH_DEFAULT
708711
{ $$ = zend_ast_list_add($1, zend_ast_create(ZEND_AST_SWITCH_CASE, NULL, $4)); }
709712
;
710713

@@ -716,7 +719,7 @@ case_separator:
716719

717720
match:
718721
T_MATCH '(' expr ')' '{' match_arm_list '}'
719-
{ $$ = zend_ast_create(ZEND_AST_MATCH, $3, $6); };
722+
{ $$ = zend_ast_create(ZEND_AST_MATCH, $3, $6); }
720723
;
721724

722725
match_arm_list:
@@ -732,8 +735,6 @@ non_empty_match_arm_list:
732735
match_arm:
733736
match_arm_cond_list possible_comma T_DOUBLE_ARROW expr
734737
{ $$ = zend_ast_create(ZEND_AST_MATCH_ARM, $1, $4); }
735-
| T_DEFAULT possible_comma T_DOUBLE_ARROW expr
736-
{ $$ = zend_ast_create(ZEND_AST_MATCH_ARM, NULL, $4); }
737738
;
738739

739740
match_arm_cond_list:
@@ -904,7 +905,7 @@ non_empty_argument_list:
904905
;
905906

906907
argument:
907-
expr_with_default { $$ = $1; }
908+
expr { $$ = $1; }
908909
| identifier ':' expr
909910
{ $$ = zend_ast_create(ZEND_AST_NAMED_ARG, $1, $3); }
910911
| T_ELLIPSIS expr { $$ = zend_ast_create(ZEND_AST_UNPACK, $2); }
@@ -1321,15 +1322,12 @@ expr:
13211322
| inline_function { $$ = $1; }
13221323
| attributes inline_function { $$ = zend_ast_with_attributes($2, $1); }
13231324
| T_STATIC inline_function { $$ = $2; ((zend_ast_decl *) $$)->flags |= ZEND_ACC_STATIC; }
1325+
| T_DEFAULT { $$ = zend_ast_create(ZEND_AST_DEFAULT); }
13241326
| attributes T_STATIC inline_function
13251327
{ $$ = zend_ast_with_attributes($3, $1); ((zend_ast_decl *) $$)->flags |= ZEND_ACC_STATIC; }
13261328
| match { $$ = $1; }
13271329
;
13281330

1329-
expr_with_default:
1330-
expr { $$ = $1; }
1331-
| T_DEFAULT { $$ = zend_ast_create(ZEND_AST_DEFAULT); }
1332-
;
13331331

13341332
inline_function:
13351333
function returns_ref backup_doc_comment '(' parameter_list ')' lexical_vars return_type

Zend/zend_vm_def.h

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9815,10 +9815,6 @@ ZEND_VM_HANDLER(210, ZEND_FETCH_DEFAULT_ARG, UNUSED|NUM, UNUSED)
98159815

98169816
zend_function *called_func = EX(call)->func;
98179817

9818-
zend_string *reflection_class_name = ZSTR_INIT_LITERAL("ReflectionParameter", 0);
9819-
zend_class_entry *reflection_class = zend_fetch_class(reflection_class_name, ZEND_FETCH_CLASS_DEFAULT);
9820-
zend_string_release(reflection_class_name);
9821-
98229818
/*
98239819
* [0]: The function (string) or class method (array) to reflect parameters from.
98249820
* [1]: A zero-based integer specifying the parameter position.
@@ -9837,12 +9833,12 @@ ZEND_VM_HANDLER(210, ZEND_FETCH_DEFAULT_ARG, UNUSED|NUM, UNUSED)
98379833

98389834
zval reflection_obj;
98399835
// TODO: Check result.
9840-
/*zend_result res =*/ object_init_with_constructor(&reflection_obj, reflection_class, 2, constructor_params, NULL);
9836+
/*zend_result res =*/ object_init_with_constructor(&reflection_obj, reflection_parameter_ptr, 2, constructor_params, NULL);
98419837
zval_ptr_dtor(&constructor_params[0]);
98429838
zval_ptr_dtor(&constructor_params[1]);
98439839

98449840
zval default_value;
9845-
zend_call_method_with_0_params(Z_OBJ(reflection_obj), reflection_class, NULL, "getDefaultValue", &default_value);
9841+
zend_call_method_with_0_params(Z_OBJ(reflection_obj), reflection_parameter_ptr, NULL, "getDefaultValue", &default_value);
98469842
zval_ptr_dtor(&reflection_obj);
98479843

98489844
ZVAL_COPY(EX_VAR(opline->result.var), &default_value);

Zend/zend_vm_execute.h

Lines changed: 2 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)