Skip to content

Commit fb65dbe

Browse files
committed
Cleanup argument handling in ext/reflection
1 parent 69a5c56 commit fb65dbe

19 files changed

+307
-247
lines changed

Zend/zend_API.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,12 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_error(int error_code,
234234
case ZPP_ERROR_WRONG_STRING_OR_CLASS_OR_NULL:
235235
zend_wrong_parameter_string_or_class_or_null_error(num, name, arg);
236236
break;
237+
case ZPP_ERROR_WRONG_CLASS_NAME_OR_CLASS:
238+
zend_wrong_parameter_class_name_or_class_error(num, name, arg);
239+
break;
240+
case ZPP_ERROR_WRONG_CLASS_NAME_OR_CLASS_OR_NULL:
241+
zend_wrong_parameter_class_name_or_class_or_null_error(num, name, arg);
242+
break;
237243
default:
238244
ZEND_ASSERT(error_code != ZPP_ERROR_OK);
239245
}
@@ -295,6 +301,26 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_string_or_class_or_nu
295301
}
296302
/* }}} */
297303

304+
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_name_or_class_error(uint32_t num, const char *name, zval *arg) /* {{{ */
305+
{
306+
if (EG(exception)) {
307+
return;
308+
}
309+
310+
zend_argument_type_error(num, "must be a valid class name or an object of type %s, %s given", name, zend_zval_type_name(arg));
311+
}
312+
/* }}} */
313+
314+
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_name_or_class_or_null_error(uint32_t num, const char *name, zval *arg) /* {{{ */
315+
{
316+
if (EG(exception)) {
317+
return;
318+
}
319+
320+
zend_argument_type_error(num, "must be either a valid class name, or an object of type %s, or null, %s given", name, zend_zval_type_name(arg));
321+
}
322+
/* }}} */
323+
298324
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(uint32_t num, char *error) /* {{{ */
299325
{
300326
if (EG(exception)) {

Zend/zend_API.h

Lines changed: 72 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,22 +1236,26 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_error(int error_code,
12361236
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_type_error(uint32_t num, zend_expected_type expected_type, zval *arg);
12371237
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_error(uint32_t num, const char *name, zval *arg);
12381238
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_null_error(uint32_t num, const char *name, zval *arg);
1239+
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_name_or_class_error(uint32_t num, const char *name, zval *arg);
1240+
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_name_or_class_or_null_error(uint32_t num, const char *name, zval *arg);
12391241
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_string_or_class_error(uint32_t num, const char *name, zval *arg);
12401242
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_string_or_class_or_null_error(uint32_t num, const char *name, zval *arg);
12411243
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(uint32_t num, char *error);
12421244
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_error(zend_class_entry *error_ce, uint32_t arg_num, const char *format, ...);
12431245
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_type_error(uint32_t arg_num, const char *format, ...);
12441246
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_value_error(uint32_t arg_num, const char *format, ...);
12451247

1246-
#define ZPP_ERROR_OK 0
1247-
#define ZPP_ERROR_FAILURE 1
1248-
#define ZPP_ERROR_WRONG_CALLBACK 2
1249-
#define ZPP_ERROR_WRONG_CLASS 3
1250-
#define ZPP_ERROR_WRONG_CLASS_OR_NULL 4
1251-
#define ZPP_ERROR_WRONG_ARG 5
1252-
#define ZPP_ERROR_WRONG_COUNT 6
1253-
#define ZPP_ERROR_WRONG_STRING_OR_CLASS 7
1254-
#define ZPP_ERROR_WRONG_STRING_OR_CLASS_OR_NULL 8
1248+
#define ZPP_ERROR_OK 0
1249+
#define ZPP_ERROR_FAILURE 1
1250+
#define ZPP_ERROR_WRONG_CALLBACK 2
1251+
#define ZPP_ERROR_WRONG_CLASS 3
1252+
#define ZPP_ERROR_WRONG_CLASS_OR_NULL 4
1253+
#define ZPP_ERROR_WRONG_ARG 5
1254+
#define ZPP_ERROR_WRONG_COUNT 6
1255+
#define ZPP_ERROR_WRONG_STRING_OR_CLASS 7
1256+
#define ZPP_ERROR_WRONG_STRING_OR_CLASS_OR_NULL 8
1257+
#define ZPP_ERROR_WRONG_CLASS_NAME_OR_CLASS 9
1258+
#define ZPP_ERROR_WRONG_CLASS_NAME_OR_CLASS_OR_NULL 10
12551259

12561260
#define ZEND_PARSE_PARAMETERS_START_EX(flags, min_num_args, max_num_args) do { \
12571261
const int _flags = (flags); \
@@ -1408,6 +1412,40 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_value_error(uint32_t arg_num
14081412
#define Z_PARAM_CLASS_NAME_OR_OBJ_OR_NULL(dest) \
14091413
Z_PARAM_CLASS_NAME_OR_OBJ_EX(dest, 1);
14101414

1415+
#define Z_PARAM_CLASS_NAME_CE_OR_OBJ_EX(dest_ce, dest_obj, allow_null) \
1416+
Z_PARAM_PROLOGUE(0, 0); \
1417+
if (UNEXPECTED(!zend_parse_arg_class_name_ce_or_obj(_arg, &dest_ce, &dest_obj, NULL, allow_null))) { \
1418+
_expected_type = allow_null ? Z_EXPECTED_CLASS_NAME_OR_OBJECT_OR_NULL : Z_EXPECTED_CLASS_NAME_OR_OBJECT; \
1419+
_error_code = ZPP_ERROR_WRONG_ARG; \
1420+
break; \
1421+
}
1422+
1423+
#define Z_PARAM_CLASS_NAME_CE_OR_OBJ(dest_ce, dest_obj) \
1424+
Z_PARAM_CLASS_NAME_CE_OR_OBJ_EX(dest_ce, dest_obj, 0);
1425+
1426+
#define Z_PARAM_CLASS_NAME_CE_OR_OBJ_OR_NULL(dest_ce, dest_obj) \
1427+
Z_PARAM_CLASS_NAME_CE_OR_OBJ_EX(dest_ce, dest_obj, 1);
1428+
1429+
#define Z_PARAM_CLASS_NAME_CE_OR_OBJ_OF_CLASS_EX(dest_ce, dest_obj, base_ce, allow_null) \
1430+
Z_PARAM_PROLOGUE(0, 0); \
1431+
if (UNEXPECTED(!zend_parse_arg_class_name_ce_or_obj(_arg, &dest_ce, &dest_obj, base_ce, allow_null))) { \
1432+
if (base_ce) { \
1433+
_error = ZSTR_VAL((base_ce)->name); \
1434+
_error_code = allow_null ? ZPP_ERROR_WRONG_CLASS_NAME_OR_CLASS_OR_NULL : ZPP_ERROR_WRONG_CLASS_NAME_OR_CLASS; \
1435+
break; \
1436+
} else { \
1437+
_expected_type = allow_null ? Z_EXPECTED_CLASS_NAME_OR_OBJECT_OR_NULL : Z_EXPECTED_CLASS_NAME_OR_OBJECT_OR_NULL; \
1438+
_error_code = ZPP_ERROR_WRONG_ARG; \
1439+
break; \
1440+
} \
1441+
}
1442+
1443+
#define Z_PARAM_CLASS_NAME_CE_OR_OBJ_OF_CLASS(dest_ce, dest_obj, base_ce) \
1444+
Z_PARAM_CLASS_NAME_CE_OR_OBJ_OF_CLASS_EX(dest_ce, dest_obj, base_ce, 0);
1445+
1446+
#define Z_PARAM_CLASS_NAME_CE_OR_OBJ_OF_CLASS_OR_NULL(dest_ce, dest_obj, base_ce) \
1447+
Z_PARAM_CLASS_NAME_CE_OR_OBJ_OF_CLASS_EX(dest_ce, dest_obj, base_ce, 1);
1448+
14111449
#define Z_PARAM_STR_OR_OBJ_EX(destination_string, destination_object, allow_null) \
14121450
Z_PARAM_PROLOGUE(0, 0); \
14131451
if (UNEXPECTED(!zend_parse_arg_str_or_obj(_arg, &destination_string, &destination_object, NULL, allow_null))) { \
@@ -2003,6 +2041,31 @@ static zend_always_inline int zend_parse_arg_class_name_or_obj(
20032041
return 1;
20042042
}
20052043

2044+
static zend_always_inline int zend_parse_arg_class_name_ce_or_obj(
2045+
zval *arg, zend_class_entry **destination_ce, zend_object **destination_object, zend_class_entry *base_ce, int allow_null
2046+
) {
2047+
if (EXPECTED(Z_TYPE_P(arg) == IS_OBJECT)) {
2048+
if (base_ce && UNEXPECTED(!instanceof_function(Z_OBJCE_P(arg), base_ce))) {
2049+
return 0;
2050+
}
2051+
2052+
*destination_object = Z_OBJ_P(arg);
2053+
*destination_ce = NULL;
2054+
} else if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) {
2055+
*destination_object = NULL;
2056+
*destination_ce = zend_lookup_class(Z_STR_P(arg));
2057+
2058+
return *destination_ce != NULL;
2059+
} else if (allow_null && EXPECTED(Z_TYPE_P(arg) == IS_NULL)) {
2060+
*destination_ce = NULL;
2061+
*destination_object = NULL;
2062+
} else {
2063+
return 0;
2064+
}
2065+
2066+
return 1;
2067+
}
2068+
20062069
static zend_always_inline int zend_parse_arg_str_or_obj(
20072070
zval *arg, zend_string **destination_string, zend_object **destination_object, zend_class_entry *base_ce, int allow_null
20082071
) {

Zend/zend_closures.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,13 @@ ZEND_API const zend_function *zend_get_closure_method_def(zval *obj) /* {{{ */
401401
}
402402
/* }}} */
403403

404+
ZEND_API const zend_function *zend_get_closure_method_def_from_obj(zend_object *obj) /* {{{ */
405+
{
406+
zend_closure *closure = (zend_closure *) obj;
407+
return &closure->func;
408+
}
409+
/* }}} */
410+
404411
ZEND_API zval* zend_get_closure_this_ptr(zval *obj) /* {{{ */
405412
{
406413
zend_closure *closure = (zend_closure *)Z_OBJ_P(obj);

Zend/zend_closures.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ ZEND_API void zend_create_closure(zval *res, zend_function *op_array, zend_class
3636
ZEND_API void zend_create_fake_closure(zval *res, zend_function *op_array, zend_class_entry *scope, zend_class_entry *called_scope, zval *this_ptr);
3737
ZEND_API zend_function *zend_get_closure_invoke_method(zend_object *obj);
3838
ZEND_API const zend_function *zend_get_closure_method_def(zval *obj);
39+
ZEND_API const zend_function *zend_get_closure_method_def_from_obj(zend_object *obj);
3940
ZEND_API zval* zend_get_closure_this_ptr(zval *obj);
4041

4142
END_EXTERN_C()

0 commit comments

Comments
 (0)