Skip to content

Commit 1edecb8

Browse files
committed
Store parameter default values in arginfo
1 parent a54ee6e commit 1edecb8

15 files changed

+283
-198
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ PHP NEWS
100100
. Fixed bug #69180 (Reflection does not honor trait conflict resolution /
101101
method aliasing). (Nikita)
102102
. Fixed bug #74939 (Nested traits' aliased methods are lowercased). (Nikita)
103+
. Implement ReflectionParameter::getDefaultValueString (kocsismate)
103104

104105
- Session:
105106
. Fixed bug #78624 (session_gc return value for user defined session

UPGRADING

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,14 @@ PHP 8.0 UPGRADE NOTES
319319
result will include a nullability indicator for nullable types. The format
320320
of the return value is not stable and may change between PHP versions.
321321
. Reflection export() methods have been removed.
322+
. The following methods can now return information about default values of
323+
parameters of internal functions:
324+
ReflectionParameter::isDefaultValueAvailable()
325+
ReflectionParameter::getDefaultValue()
326+
ReflectionParameter::isDefaultValueConstant()
327+
ReflectionParameter::getDefaultValueConstantName()
328+
. The ReflectionParameter::isDefaultValueConstant() and
329+
ReflectionParameter::getDefaultValueConstantName() methods have been deprecated.
322330

323331
- Socket:
324332
. The deprecated AI_IDN_ALLOW_UNASSIGNED and AI_IDN_USE_STD3_ASCII_RULES

Zend/zend_API.h

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -105,50 +105,61 @@ typedef struct _zend_fcall_info_cache {
105105
#define _ZEND_ARG_INFO_FLAGS(pass_by_ref, is_variadic) \
106106
(((pass_by_ref) << _ZEND_SEND_MODE_SHIFT) | ((is_variadic) ? _ZEND_IS_VARIADIC_BIT : 0))
107107

108+
/* Arginfo structures without type information */
108109
#define ZEND_ARG_INFO(pass_by_ref, name) \
109-
{ #name, ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(pass_by_ref, 0))},
110-
#define ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null) \
111-
{ #name, ZEND_TYPE_INIT_CLASS_CONST(#classname, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)) },
112-
#define ZEND_ARG_ARRAY_INFO(pass_by_ref, name, allow_null) \
113-
{ #name, ZEND_TYPE_INIT_CODE(IS_ARRAY, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)) },
114-
#define ZEND_ARG_CALLABLE_INFO(pass_by_ref, name, allow_null) \
115-
{ #name, ZEND_TYPE_INIT_CODE(IS_CALLABLE, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)) },
116-
#define ZEND_ARG_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) \
117-
{ #name, ZEND_TYPE_INIT_CODE(type_hint, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)) },
118-
#define ZEND_ARG_TYPE_MASK(pass_by_ref, name, type_mask) \
119-
{ #name, ZEND_TYPE_INIT_MASK(type_mask | _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)) },
110+
{ #name, ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), NULL },
111+
#define ZEND_ARG_INFO_WITH_DEFAULT_VALUE(pass_by_ref, name, default_value) \
112+
{ #name, ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), default_value },
120113
#define ZEND_ARG_VARIADIC_INFO(pass_by_ref, name) \
121-
{ #name, ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(pass_by_ref, 1)) },
114+
{ #name, ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(pass_by_ref, 1)), NULL },
115+
/* Arginfo structures with simple type information */
116+
#define ZEND_ARG_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) \
117+
{ #name, ZEND_TYPE_INIT_CODE(type_hint, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), NULL },
118+
#define ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(pass_by_ref, name, type_hint, allow_null, default_value) \
119+
{ #name, ZEND_TYPE_INIT_CODE(type_hint, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), default_value },
122120
#define ZEND_ARG_VARIADIC_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) \
123-
{ #name, ZEND_TYPE_INIT_CODE(type_hint, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 1)) },
121+
{ #name, ZEND_TYPE_INIT_CODE(type_hint, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 1)), NULL },
122+
/* Arginfo structures with complex type information */
123+
#define ZEND_ARG_TYPE_MASK(pass_by_ref, name, type_mask, default_value) \
124+
{ #name, ZEND_TYPE_INIT_MASK(type_mask | _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), default_value },
125+
/* Arginfo structures with object type information */
126+
#define ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null) \
127+
{ #name, ZEND_TYPE_INIT_CLASS_CONST(#classname, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), NULL },
128+
#define ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(pass_by_ref, name, classname, allow_null, default_value) \
129+
{ #name, ZEND_TYPE_INIT_CLASS_CONST(#classname, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), default_value },
124130
#define ZEND_ARG_VARIADIC_OBJ_INFO(pass_by_ref, name, classname, allow_null) \
125-
{ #name, ZEND_TYPE_INIT_CLASS_CONST(#classname, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 1)) },
131+
{ #name, ZEND_TYPE_INIT_CLASS_CONST(#classname, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 1)), NULL },
132+
/* Legacy arginfo structures */
133+
#define ZEND_ARG_ARRAY_INFO(pass_by_ref, name, allow_null) \
134+
{ #name, ZEND_TYPE_INIT_CODE(IS_ARRAY, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), NULL },
135+
#define ZEND_ARG_CALLABLE_INFO(pass_by_ref, name, allow_null) \
136+
{ #name, ZEND_TYPE_INIT_CODE(IS_CALLABLE, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), NULL },
126137

127138
#define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(name, return_reference, required_num_args, class_name, allow_null) \
128139
static const zend_internal_arg_info name[] = { \
129140
{ (const char*)(zend_uintptr_t)(required_num_args), \
130-
ZEND_TYPE_INIT_CLASS_CONST(#class_name, allow_null, _ZEND_ARG_INFO_FLAGS(return_reference, 0)) },
141+
ZEND_TYPE_INIT_CLASS_CONST(#class_name, allow_null, _ZEND_ARG_INFO_FLAGS(return_reference, 0)), NULL },
131142

132143
#define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO(name, class_name, allow_null) \
133144
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(name, 0, -1, class_name, allow_null)
134145

135146
#define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(name, return_reference, required_num_args, type) \
136147
static const zend_internal_arg_info name[] = { \
137-
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_MASK(type | _ZEND_ARG_INFO_FLAGS(return_reference, 0)) },
148+
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_MASK(type | _ZEND_ARG_INFO_FLAGS(return_reference, 0)), NULL },
138149

139150
#define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(name, return_reference, required_num_args, class_name, type) \
140151
static const zend_internal_arg_info name[] = { \
141-
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_CLASS_CONST_MASK(#class_name, type | _ZEND_ARG_INFO_FLAGS(return_reference, 0)) },
152+
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_CLASS_CONST_MASK(#class_name, type | _ZEND_ARG_INFO_FLAGS(return_reference, 0)), NULL },
142153

143154
#define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, type, allow_null) \
144155
static const zend_internal_arg_info name[] = { \
145-
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_CODE(type, allow_null, _ZEND_ARG_INFO_FLAGS(return_reference, 0)) },
156+
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_CODE(type, allow_null, _ZEND_ARG_INFO_FLAGS(return_reference, 0)), NULL },
146157
#define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO(name, type, allow_null) \
147158
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, 0, -1, type, allow_null)
148159

149160
#define ZEND_BEGIN_ARG_INFO_EX(name, _unused, return_reference, required_num_args) \
150161
static const zend_internal_arg_info name[] = { \
151-
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(return_reference, 0)) },
162+
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(return_reference, 0)), NULL },
152163
#define ZEND_BEGIN_ARG_INFO(name, _unused) \
153164
ZEND_BEGIN_ARG_INFO_EX(name, {}, ZEND_RETURN_VALUE, -1)
154165
#define ZEND_END_ARG_INFO() };

Zend/zend_builtin_functions_arginfo.h

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@ ZEND_END_ARG_INFO()
3232

3333
#define arginfo_strncasecmp arginfo_strncmp
3434

35-
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_error_reporting, 0, 0, IS_LONG, 1)
35+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_error_reporting, 0, 0, IS_LONG, 0)
3636
ZEND_ARG_INFO(0, new_error_level)
3737
ZEND_END_ARG_INFO()
3838

3939
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_define, 0, 2, _IS_BOOL, 0)
4040
ZEND_ARG_TYPE_INFO(0, constant_name, IS_STRING, 0)
4141
ZEND_ARG_INFO(0, value)
42-
ZEND_ARG_TYPE_INFO(0, case_insensitive, _IS_BOOL, 0)
42+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, case_insensitive, _IS_BOOL, 0, "false")
4343
ZEND_END_ARG_INFO()
4444

4545
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_defined, 0, 1, _IS_BOOL, 0)
@@ -59,10 +59,14 @@ ZEND_END_ARG_INFO()
5959
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_is_subclass_of, 0, 2, _IS_BOOL, 0)
6060
ZEND_ARG_INFO(0, object)
6161
ZEND_ARG_TYPE_INFO(0, class_name, IS_STRING, 0)
62-
ZEND_ARG_TYPE_INFO(0, allow_string, _IS_BOOL, 0)
62+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, allow_string, _IS_BOOL, 0, "true")
6363
ZEND_END_ARG_INFO()
6464

65-
#define arginfo_is_a arginfo_is_subclass_of
65+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_is_a, 0, 2, _IS_BOOL, 0)
66+
ZEND_ARG_INFO(0, object)
67+
ZEND_ARG_TYPE_INFO(0, class_name, IS_STRING, 0)
68+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, allow_string, _IS_BOOL, 0, "false")
69+
ZEND_END_ARG_INFO()
6670

6771
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_get_class_vars, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE)
6872
ZEND_ARG_TYPE_INFO(0, class_name, IS_STRING, 0)
@@ -90,14 +94,14 @@ ZEND_END_ARG_INFO()
9094

9195
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_exists, 0, 1, _IS_BOOL, 0)
9296
ZEND_ARG_TYPE_INFO(0, classname, IS_STRING, 0)
93-
ZEND_ARG_TYPE_INFO(0, autoload, _IS_BOOL, 0)
97+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, autoload, _IS_BOOL, 0, "true")
9498
ZEND_END_ARG_INFO()
9599

96100
#define arginfo_interface_exists arginfo_class_exists
97101

98102
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_trait_exists, 0, 1, _IS_BOOL, 0)
99103
ZEND_ARG_TYPE_INFO(0, traitname, IS_STRING, 0)
100-
ZEND_ARG_TYPE_INFO(0, autoload, _IS_BOOL, 0)
104+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, autoload, _IS_BOOL, 0, "true")
101105
ZEND_END_ARG_INFO()
102106

103107
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_function_exists, 0, 1, _IS_BOOL, 0)
@@ -107,7 +111,7 @@ ZEND_END_ARG_INFO()
107111
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_alias, 0, 2, _IS_BOOL, 0)
108112
ZEND_ARG_TYPE_INFO(0, user_class_name, IS_STRING, 0)
109113
ZEND_ARG_TYPE_INFO(0, alias_name, IS_STRING, 0)
110-
ZEND_ARG_TYPE_INFO(0, autoload, _IS_BOOL, 0)
114+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, autoload, _IS_BOOL, 0, "true")
111115
ZEND_END_ARG_INFO()
112116

113117
#define arginfo_get_included_files arginfo_func_get_args
@@ -116,14 +120,14 @@ ZEND_END_ARG_INFO()
116120

117121
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_trigger_error, 0, 1, _IS_BOOL, 0)
118122
ZEND_ARG_TYPE_INFO(0, message, IS_STRING, 0)
119-
ZEND_ARG_TYPE_INFO(0, error_type, IS_LONG, 0)
123+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, error_type, IS_LONG, 0, "E_USER_NOTICE")
120124
ZEND_END_ARG_INFO()
121125

122126
#define arginfo_user_error arginfo_trigger_error
123127

124128
ZEND_BEGIN_ARG_INFO_EX(arginfo_set_error_handler, 0, 0, 1)
125129
ZEND_ARG_INFO(0, error_handler)
126-
ZEND_ARG_TYPE_INFO(0, error_types, IS_LONG, 0)
130+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, error_types, IS_LONG, 0, "E_ALL")
127131
ZEND_END_ARG_INFO()
128132

129133
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_restore_error_handler, 0, 0, _IS_BOOL, 0)
@@ -142,7 +146,7 @@ ZEND_END_ARG_INFO()
142146
#define arginfo_get_declared_interfaces arginfo_func_get_args
143147

144148
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_get_defined_functions, 0, 0, IS_ARRAY, 0)
145-
ZEND_ARG_TYPE_INFO(0, exclude_disabled, _IS_BOOL, 0)
149+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, exclude_disabled, _IS_BOOL, 0, "false")
146150
ZEND_END_ARG_INFO()
147151

148152
#define arginfo_get_defined_vars arginfo_func_get_args
@@ -156,21 +160,21 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_get_resources, 0, 0, IS_ARRAY, 0
156160
ZEND_END_ARG_INFO()
157161

158162
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_get_loaded_extensions, 0, 0, IS_ARRAY, 0)
159-
ZEND_ARG_TYPE_INFO(0, zend_extensions, _IS_BOOL, 0)
163+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, zend_extensions, _IS_BOOL, 0, "false")
160164
ZEND_END_ARG_INFO()
161165

162166
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_get_defined_constants, 0, 0, IS_ARRAY, 0)
163-
ZEND_ARG_TYPE_INFO(0, categorize, _IS_BOOL, 0)
167+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, categorize, _IS_BOOL, 0, "false")
164168
ZEND_END_ARG_INFO()
165169

166170
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_debug_backtrace, 0, 0, IS_ARRAY, 0)
167-
ZEND_ARG_TYPE_INFO(0, options, IS_LONG, 0)
168-
ZEND_ARG_TYPE_INFO(0, limit, IS_LONG, 0)
171+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "DEBUG_BACKTRACE_PROVIDE_OBJECT")
172+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, limit, IS_LONG, 0, "0")
169173
ZEND_END_ARG_INFO()
170174

171175
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_debug_print_backtrace, 0, 0, IS_VOID, 0)
172-
ZEND_ARG_TYPE_INFO(0, options, IS_LONG, 0)
173-
ZEND_ARG_TYPE_INFO(0, limit, IS_LONG, 0)
176+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0")
177+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, limit, IS_LONG, 0, "0")
174178
ZEND_END_ARG_INFO()
175179

176180
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_extension_loaded, 0, 1, _IS_BOOL, 0)

Zend/zend_compile.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5786,6 +5786,11 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32_t fall
57865786
zend_error_noreturn(E_COMPILE_ERROR, "Only the last parameter can be variadic");
57875787
}
57885788

5789+
arg_info = &arg_infos[i];
5790+
arg_info->name = zend_string_copy(name);
5791+
arg_info->type = (zend_type) ZEND_TYPE_INIT_NONE(0);
5792+
arg_info->default_value = NULL;
5793+
57895794
if (is_variadic) {
57905795
opcode = ZEND_RECV_VARIADIC;
57915796
default_node.op_type = IS_UNUSED;
@@ -5796,13 +5801,12 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32_t fall
57965801
"Variadic parameter cannot have a default value");
57975802
}
57985803
} else if (default_ast) {
5799-
/* we cannot substitute constants here or it will break ReflectionParameter::getDefaultValueConstantName() and ReflectionParameter::isDefaultValueConstant() */
5800-
uint32_t cops = CG(compiler_options);
5801-
CG(compiler_options) |= ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION | ZEND_COMPILE_NO_PERSISTENT_CONSTANT_SUBSTITUTION;
5804+
zend_string *default_value_string = zend_new_interned_string(zend_ast_export("", default_ast, ""));
5805+
arg_info->default_value = zend_string_copy(default_value_string);
5806+
58025807
opcode = ZEND_RECV_INIT;
58035808
default_node.op_type = IS_CONST;
58045809
zend_const_expr_to_zval(&default_node.u.constant, default_ast);
5805-
CG(compiler_options) = cops;
58065810

58075811
if (!optional_param) {
58085812
/* Ignore parameters of the form "Type $param = null".
@@ -5823,10 +5827,6 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32_t fall
58235827
}
58245828
}
58255829

5826-
arg_info = &arg_infos[i];
5827-
arg_info->name = zend_string_copy(name);
5828-
arg_info->type = (zend_type) ZEND_TYPE_INIT_NONE(0);
5829-
58305830
if (type_ast) {
58315831
uint32_t default_type = default_ast ? Z_TYPE(default_node.u.constant) : IS_UNDEF;
58325832

Zend/zend_compile.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,12 +374,14 @@ typedef struct _zend_class_constant {
374374
typedef struct _zend_internal_arg_info {
375375
const char *name;
376376
zend_type type;
377+
const char *default_value;
377378
} zend_internal_arg_info;
378379

379380
/* arg_info for user functions */
380381
typedef struct _zend_arg_info {
381382
zend_string *name;
382383
zend_type type;
384+
zend_string *default_value;
383385
} zend_arg_info;
384386

385387
/* the following structure repeats the layout of zend_internal_arg_info,
@@ -390,6 +392,7 @@ typedef struct _zend_arg_info {
390392
typedef struct _zend_internal_function_info {
391393
zend_uintptr_t required_num_args;
392394
zend_type type;
395+
const char *default_value;
393396
} zend_internal_function_info;
394397

395398
struct _zend_op_array {

Zend/zend_exceptions_arginfo.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ ZEND_END_ARG_INFO()
1919

2020
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Exception___construct, 0, 0, 0)
2121
ZEND_ARG_TYPE_INFO(0, message, IS_STRING, 0)
22-
ZEND_ARG_TYPE_INFO(0, code, IS_LONG, 0)
23-
ZEND_ARG_OBJ_INFO(0, previous, Throwable, 1)
22+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, code, IS_LONG, 0, "0")
23+
ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, previous, Throwable, 1, "null")
2424
ZEND_END_ARG_INFO()
2525

2626
#define arginfo_class_Exception___wakeup arginfo_class_Throwable_getMessage
@@ -44,11 +44,11 @@ ZEND_END_ARG_INFO()
4444

4545
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ErrorException___construct, 0, 0, 0)
4646
ZEND_ARG_TYPE_INFO(0, message, IS_STRING, 0)
47-
ZEND_ARG_TYPE_INFO(0, code, IS_LONG, 0)
48-
ZEND_ARG_TYPE_INFO(0, severity, IS_LONG, 0)
47+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, code, IS_LONG, 0, "0")
48+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, severity, IS_LONG, 0, "E_ERROR")
4949
ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0)
50-
ZEND_ARG_TYPE_INFO(0, lineno, IS_LONG, 0)
51-
ZEND_ARG_OBJ_INFO(0, previous, Throwable, 1)
50+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, lineno, IS_LONG, 0, "0")
51+
ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, previous, Throwable, 1, "null")
5252
ZEND_END_ARG_INFO()
5353

5454
#define arginfo_class_ErrorException_getSeverity arginfo_class_Throwable_getMessage

Zend/zend_inheritance.c

Lines changed: 7 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -684,57 +684,15 @@ static ZEND_COLD zend_string *zend_get_function_declaration(const zend_function
684684

685685
if (i >= required && !ZEND_ARG_IS_VARIADIC(arg_info)) {
686686
smart_str_appends(&str, " = ");
687-
if (fptr->type == ZEND_USER_FUNCTION) {
688-
zend_op *precv = NULL;
689-
{
690-
uint32_t idx = i;
691-
zend_op *op = fptr->op_array.opcodes;
692-
zend_op *end = op + fptr->op_array.last;
693-
694-
++idx;
695-
while (op < end) {
696-
if ((op->opcode == ZEND_RECV || op->opcode == ZEND_RECV_INIT)
697-
&& op->op1.num == (zend_ulong)idx)
698-
{
699-
precv = op;
700-
}
701-
++op;
702-
}
703-
}
704-
if (precv && precv->opcode == ZEND_RECV_INIT && precv->op2_type != IS_UNUSED) {
705-
zval *zv = RT_CONSTANT(precv, precv->op2);
706-
707-
if (Z_TYPE_P(zv) == IS_FALSE) {
708-
smart_str_appends(&str, "false");
709-
} else if (Z_TYPE_P(zv) == IS_TRUE) {
710-
smart_str_appends(&str, "true");
711-
} else if (Z_TYPE_P(zv) == IS_NULL) {
712-
smart_str_appends(&str, "NULL");
713-
} else if (Z_TYPE_P(zv) == IS_STRING) {
714-
smart_str_appendc(&str, '\'');
715-
smart_str_appendl(&str, Z_STRVAL_P(zv), MIN(Z_STRLEN_P(zv), 10));
716-
if (Z_STRLEN_P(zv) > 10) {
717-
smart_str_appends(&str, "...");
718-
}
719-
smart_str_appendc(&str, '\'');
720-
} else if (Z_TYPE_P(zv) == IS_ARRAY) {
721-
smart_str_appends(&str, "Array");
722-
} else if (Z_TYPE_P(zv) == IS_CONSTANT_AST) {
723-
zend_ast *ast = Z_ASTVAL_P(zv);
724-
if (ast->kind == ZEND_AST_CONSTANT) {
725-
smart_str_append(&str, zend_ast_get_constant_name(ast));
726-
} else {
727-
smart_str_appends(&str, "<expression>");
728-
}
729-
} else {
730-
zend_string *tmp_zv_str;
731-
zend_string *zv_str = zval_get_tmp_string(zv, &tmp_zv_str);
732-
smart_str_append(&str, zv_str);
733-
zend_tmp_string_release(tmp_zv_str);
734-
}
687+
688+
if (arg_info->default_value) {
689+
if (fptr->type == ZEND_INTERNAL_FUNCTION) {
690+
smart_str_appends(&str, ((zend_internal_arg_info*)arg_info)->default_value);
691+
} else {
692+
smart_str_appends(&str, ZSTR_VAL(arg_info->default_value));
735693
}
736694
} else {
737-
smart_str_appends(&str, "NULL");
695+
smart_str_appends(&str, "<default>");
738696
}
739697
}
740698

ext/reflection/Makefile.frag

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
$(top_srcdir)/Zend/zend_language_parser.c:
2+
$(top_srcdir)/Zend/zend_language_scanner.c:
3+
$(top_srcdir)/ext/reflection/php_reflection.c: $(top_srcdir)/Zend/zend_language_parser.h
4+
$(builddir)/reflection.lo: $(top_srcdir)/Zend/zend_language_parser.c $(top_srcdir)/Zend/zend_language_scanner.c

ext/reflection/config.m4

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
PHP_NEW_EXTENSION(reflection, php_reflection.c, no,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1)
2+
PHP_ADD_MAKEFILE_FRAGMENT

0 commit comments

Comments
 (0)