Skip to content

Commit 90efcd9

Browse files
committed
ZPP: Return tristate from zend_parse_arg_bool_weak()
This idea is based on @ndossche previous PR to reduce codebloat: #18436 This effectively allows us to return the boolean value via the return type rather than using an out pointer.
1 parent 493796d commit 90efcd9

File tree

3 files changed

+32
-21
lines changed

3 files changed

+32
-21
lines changed

Zend/zend_API.c

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -509,35 +509,33 @@ static ZEND_COLD bool zend_null_arg_deprecated(const char *fallback_type, uint32
509509
return !EG(exception);
510510
}
511511

512-
ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_weak(const zval *arg, bool *dest, uint32_t arg_num) /* {{{ */
512+
ZEND_API zpp_parse_bool_status ZEND_FASTCALL zend_parse_arg_bool_weak(const zval *arg, uint32_t arg_num) /* {{{ */
513513
{
514514
if (EXPECTED(Z_TYPE_P(arg) <= IS_STRING)) {
515515
if (UNEXPECTED(Z_TYPE_P(arg) == IS_NULL) && !zend_null_arg_deprecated("bool", arg_num)) {
516-
return 0;
516+
return ZPP_PARSE_ERROR;
517517
}
518-
*dest = zend_is_true(arg);
519-
} else {
520-
return 0;
518+
return zend_is_true(arg);
521519
}
522-
return 1;
520+
return ZPP_PARSE_ERROR;
523521
}
524522
/* }}} */
525523

526-
ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_slow(const zval *arg, bool *dest, uint32_t arg_num) /* {{{ */
524+
ZEND_API zpp_parse_bool_status ZEND_FASTCALL zend_parse_arg_bool_slow(const zval *arg, uint32_t arg_num) /* {{{ */
527525
{
528526
if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
529-
return 0;
527+
return ZPP_PARSE_ERROR;
530528
}
531-
return zend_parse_arg_bool_weak(arg, dest, arg_num);
529+
return zend_parse_arg_bool_weak(arg, arg_num);
532530
}
533531
/* }}} */
534532

535-
ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_bool_slow(const zval *arg, bool *dest, uint32_t arg_num)
533+
ZEND_API zpp_parse_bool_status ZEND_FASTCALL zend_flf_parse_arg_bool_slow(const zval *arg, uint32_t arg_num)
536534
{
537535
if (UNEXPECTED(ZEND_FLF_ARG_USES_STRICT_TYPES())) {
538-
return 0;
536+
return ZPP_PARSE_ERROR;
539537
}
540-
return zend_parse_arg_bool_weak(arg, dest, arg_num);
538+
return zend_parse_arg_bool_weak(arg, arg_num);
541539
}
542540

543541
ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_weak(const zval *arg, zend_long *dest, uint32_t arg_num) /* {{{ */

Zend/zend_API.h

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2173,9 +2173,15 @@ ZEND_API ZEND_COLD void zend_class_redeclaration_error_ex(int type, zend_string
21732173

21742174
/* Inlined implementations shared by new and old parameter parsing APIs */
21752175

2176+
typedef enum ZPP_PARSE_BOOL_STATUS {
2177+
ZPP_PARSE_AS_FALSE = 0,
2178+
ZPP_PARSE_AS_TRUE = 1,
2179+
ZPP_PARSE_ERROR = 2,
2180+
} zpp_parse_bool_status;
2181+
21762182
ZEND_API bool ZEND_FASTCALL zend_parse_arg_class(zval *arg, zend_class_entry **pce, uint32_t num, bool check_null);
2177-
ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_slow(const zval *arg, bool *dest, uint32_t arg_num);
2178-
ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_weak(const zval *arg, bool *dest, uint32_t arg_num);
2183+
ZEND_API zpp_parse_bool_status ZEND_FASTCALL zend_parse_arg_bool_slow(const zval *arg, uint32_t arg_num);
2184+
ZEND_API zpp_parse_bool_status ZEND_FASTCALL zend_parse_arg_bool_weak(const zval *arg, uint32_t arg_num);
21792185
ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_slow(const zval *arg, zend_long *dest, uint32_t arg_num);
21802186
ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_weak(const zval *arg, zend_long *dest, uint32_t arg_num);
21812187
ZEND_API double ZEND_FASTCALL zend_parse_arg_double_slow(const zval *arg, uint32_t arg_num);
@@ -2186,7 +2192,7 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_slow(zval *arg, zval **dest, u
21862192
ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_or_str_slow(zval *arg, zval **dest, uint32_t arg_num);
21872193
ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_or_long_slow(zval *arg, zend_string **dest_str, zend_long *dest_long, uint32_t arg_num);
21882194

2189-
ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_bool_slow(const zval *arg, bool *dest, uint32_t arg_num);
2195+
ZEND_API zpp_parse_bool_status ZEND_FASTCALL zend_flf_parse_arg_bool_slow(const zval *arg, uint32_t arg_num);
21902196
ZEND_API zend_string* ZEND_FASTCALL zend_flf_parse_arg_str_slow(zval *arg, uint32_t arg_num);
21912197
ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_long_slow(const zval *arg, zend_long *dest, uint32_t arg_num);
21922198

@@ -2203,11 +2209,16 @@ static zend_always_inline bool zend_parse_arg_bool_ex(const zval *arg, bool *des
22032209
*is_null = 1;
22042210
*dest = 0;
22052211
} else {
2212+
zpp_parse_bool_status result;
22062213
if (frameless) {
2207-
return zend_flf_parse_arg_bool_slow(arg, dest, arg_num);
2214+
result = zend_flf_parse_arg_bool_slow(arg, arg_num);
22082215
} else {
2209-
return zend_parse_arg_bool_slow(arg, dest, arg_num);
2216+
result = zend_parse_arg_bool_slow(arg, arg_num);
2217+
}
2218+
if (UNEXPECTED(result == ZPP_PARSE_ERROR)) {
2219+
return false;
22102220
}
2221+
*dest = result;
22112222
}
22122223
return 1;
22132224
}

Zend/zend_execute.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -733,7 +733,6 @@ static bool zend_verify_weak_scalar_type_hint(uint32_t type_mask, zval *arg)
733733
{
734734
zend_long lval;
735735
double dval;
736-
bool bval;
737736

738737
/* Type preference order: int -> float -> string -> bool */
739738
if (type_mask & MAY_BE_LONG) {
@@ -771,7 +770,11 @@ static bool zend_verify_weak_scalar_type_hint(uint32_t type_mask, zval *arg)
771770
/* on success "arg" is converted to IS_STRING */
772771
return true;
773772
}
774-
if ((type_mask & MAY_BE_BOOL) == MAY_BE_BOOL && zend_parse_arg_bool_weak(arg, &bval, 0)) {
773+
if ((type_mask & MAY_BE_BOOL) == MAY_BE_BOOL) {
774+
zpp_parse_bool_status bval = zend_parse_arg_bool_weak(arg, 0);
775+
if (UNEXPECTED(bval == ZPP_PARSE_ERROR)) {
776+
return false;
777+
}
775778
zval_ptr_dtor(arg);
776779
ZVAL_BOOL(arg, bval);
777780
return true;
@@ -795,7 +798,6 @@ static bool can_convert_to_string(const zval *zv) {
795798
static bool zend_verify_weak_scalar_type_hint_no_sideeffect(uint32_t type_mask, const zval *arg)
796799
{
797800
zend_long lval;
798-
bool bval;
799801

800802
/* Pass (uint32_t)-1 as arg_num to indicate to ZPP not to emit any deprecation notice,
801803
* this is needed because the version with side effects also uses 0 (e.g. for typed properties) */
@@ -808,7 +810,7 @@ static bool zend_verify_weak_scalar_type_hint_no_sideeffect(uint32_t type_mask,
808810
if ((type_mask & MAY_BE_STRING) && can_convert_to_string(arg)) {
809811
return true;
810812
}
811-
if ((type_mask & MAY_BE_BOOL) == MAY_BE_BOOL && zend_parse_arg_bool_weak(arg, &bval, (uint32_t)-1)) {
813+
if ((type_mask & MAY_BE_BOOL) == MAY_BE_BOOL && zend_parse_arg_bool_weak(arg, (uint32_t)-1) != ZPP_PARSE_ERROR) {
812814
return true;
813815
}
814816
return false;

0 commit comments

Comments
 (0)