Skip to content

Commit 863dac5

Browse files
committed
wip
1 parent d9a5d52 commit 863dac5

File tree

3 files changed

+87
-50
lines changed

3 files changed

+87
-50
lines changed

Zend/zend_API.c

Lines changed: 42 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -523,35 +523,42 @@ static ZEND_COLD bool zend_null_arg_deprecated(const char *fallback_type, uint32
523523
return !EG(exception);
524524
}
525525

526-
ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_weak(const zval *arg, bool *dest, uint32_t arg_num) /* {{{ */
526+
ZEND_API zend_opt_bool ZEND_FASTCALL zend_parse_arg_bool_weak(const zval *arg, uint32_t arg_num) /* {{{ */
527527
{
528+
zend_opt_bool result;
528529
if (EXPECTED(Z_TYPE_P(arg) <= IS_STRING)) {
529530
if (UNEXPECTED(Z_TYPE_P(arg) == IS_NULL) && !zend_null_arg_deprecated("bool", arg_num)) {
530-
return 0;
531+
result.has_value = false;
532+
return result;
531533
}
532-
*dest = zend_is_true(arg);
534+
result.value = zend_is_true(arg);
535+
result.has_value = true;
533536
} else {
534-
return 0;
537+
result.has_value = false;
535538
}
536-
return 1;
539+
return result;
537540
}
538541
/* }}} */
539542

540-
ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_slow(const zval *arg, bool *dest, uint32_t arg_num) /* {{{ */
543+
ZEND_API zend_opt_bool ZEND_FASTCALL zend_parse_arg_bool_slow(const zval *arg, uint32_t arg_num) /* {{{ */
541544
{
542545
if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
543-
return 0;
546+
zend_opt_bool result;
547+
result.has_value = false;
548+
return result;
544549
}
545-
return zend_parse_arg_bool_weak(arg, dest, arg_num);
550+
return zend_parse_arg_bool_weak(arg, arg_num);
546551
}
547552
/* }}} */
548553

549-
ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_bool_slow(const zval *arg, bool *dest, uint32_t arg_num)
554+
ZEND_API zend_opt_bool ZEND_FASTCALL zend_flf_parse_arg_bool_slow(const zval *arg, uint32_t arg_num)
550555
{
551556
if (UNEXPECTED(ZEND_FLF_ARG_USES_STRICT_TYPES())) {
552-
return 0;
557+
zend_opt_bool result;
558+
result.has_value = false;
559+
return result;
553560
}
554-
return zend_parse_arg_bool_weak(arg, dest, arg_num);
561+
return zend_parse_arg_bool_weak(arg, arg_num);
555562
}
556563

557564
ZEND_API zend_opt_long ZEND_FASTCALL zend_parse_arg_long_weak(const zval *arg, uint32_t arg_num) /* {{{ */
@@ -653,47 +660,54 @@ ZEND_API zend_opt_long ZEND_FASTCALL zend_flf_parse_arg_long_slow(const zval *ar
653660
return zend_parse_arg_long_weak(arg, arg_num);
654661
}
655662

656-
ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_weak(const zval *arg, double *dest, uint32_t arg_num) /* {{{ */
663+
ZEND_API zend_opt_double ZEND_FASTCALL zend_parse_arg_double_weak(const zval *arg, uint32_t arg_num) /* {{{ */
657664
{
665+
zend_opt_double result;
658666
if (EXPECTED(Z_TYPE_P(arg) == IS_LONG)) {
659-
*dest = (double)Z_LVAL_P(arg);
667+
result.value = (double)Z_LVAL_P(arg);
660668
} else if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) {
661669
zend_long l;
662670
uint8_t type;
663671

664-
if (UNEXPECTED((type = is_numeric_str_function(Z_STR_P(arg), &l, dest)) != IS_DOUBLE)) {
672+
if (UNEXPECTED((type = is_numeric_str_function(Z_STR_P(arg), &l, &result.value)) != IS_DOUBLE)) {
665673
if (EXPECTED(type != 0)) {
666-
*dest = (double)(l);
667-
} else {
668-
return 0;
674+
result.value = (double)(l);
675+
result.has_value = true;
669676
}
677+
return result;
670678
}
671679
if (UNEXPECTED(EG(exception))) {
672-
return 0;
680+
result.has_value = false;
681+
return result;
673682
}
674683
} else if (EXPECTED(Z_TYPE_P(arg) < IS_TRUE)) {
675684
if (UNEXPECTED(Z_TYPE_P(arg) == IS_NULL) && !zend_null_arg_deprecated("float", arg_num)) {
676-
return 0;
685+
result.has_value = false;
686+
return result;
677687
}
678-
*dest = 0.0;
688+
result.value = 0.0;
679689
} else if (EXPECTED(Z_TYPE_P(arg) == IS_TRUE)) {
680-
*dest = 1.0;
681-
} else {
682-
return 0;
690+
result.value = 1.0;
683691
}
684-
return 1;
692+
result.has_value = true;
693+
return result;
685694
}
686695
/* }}} */
687696

688-
ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_slow(const zval *arg, double *dest, uint32_t arg_num) /* {{{ */
697+
ZEND_API zend_opt_double ZEND_FASTCALL zend_parse_arg_double_slow(const zval *arg, uint32_t arg_num) /* {{{ */
689698
{
690699
if (EXPECTED(Z_TYPE_P(arg) == IS_LONG)) {
691700
/* SSTH Exception: IS_LONG may be accepted instead as IS_DOUBLE */
692-
*dest = (double)Z_LVAL_P(arg);
701+
zend_opt_double result;
702+
result.has_value = true;
703+
result.value = (double)Z_LVAL_P(arg);
704+
return result;
693705
} else if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
694-
return 0;
706+
zend_opt_double result;
707+
result.has_value = false;
708+
return result;
695709
}
696-
return zend_parse_arg_double_weak(arg, dest, arg_num);
710+
return zend_parse_arg_double_weak(arg, arg_num);
697711
}
698712
/* }}} */
699713

Zend/zend_API.h

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2179,20 +2179,30 @@ typedef struct {
21792179
bool has_value;
21802180
} zend_opt_long;
21812181

2182+
typedef struct {
2183+
bool value;
2184+
bool has_value;
2185+
} zend_opt_bool;
2186+
2187+
typedef struct {
2188+
double value;
2189+
bool has_value;
2190+
} zend_opt_double;
2191+
21822192
ZEND_API bool ZEND_FASTCALL zend_parse_arg_class(zval *arg, zend_class_entry **pce, uint32_t num, bool check_null);
2183-
ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_slow(const zval *arg, bool *dest, uint32_t arg_num);
2184-
ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_weak(const zval *arg, bool *dest, uint32_t arg_num);
2193+
ZEND_API zend_opt_bool ZEND_FASTCALL zend_parse_arg_bool_slow(const zval *arg, uint32_t arg_num);
2194+
ZEND_API zend_opt_bool ZEND_FASTCALL zend_parse_arg_bool_weak(const zval *arg, uint32_t arg_num);
21852195
ZEND_API zend_opt_long ZEND_FASTCALL zend_parse_arg_long_slow(const zval *arg, uint32_t arg_num);
21862196
ZEND_API zend_opt_long ZEND_FASTCALL zend_parse_arg_long_weak(const zval *arg, uint32_t arg_num);
2187-
ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_slow(const zval *arg, double *dest, uint32_t arg_num);
2188-
ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_weak(const zval *arg, double *dest, uint32_t arg_num);
2197+
ZEND_API zend_opt_double ZEND_FASTCALL zend_parse_arg_double_slow(const zval *arg, uint32_t arg_num);
2198+
ZEND_API zend_opt_double ZEND_FASTCALL zend_parse_arg_double_weak(const zval *arg, uint32_t arg_num);
21892199
ZEND_API zend_string * ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, uint32_t arg_num);
21902200
ZEND_API zend_string * ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, uint32_t arg_num);
21912201
ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_slow(zval *arg, zval **dest, uint32_t arg_num);
21922202
ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_or_str_slow(zval *arg, zval **dest, uint32_t arg_num);
21932203
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);
21942204

2195-
ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_bool_slow(const zval *arg, bool *dest, uint32_t arg_num);
2205+
ZEND_API zend_opt_bool ZEND_FASTCALL zend_flf_parse_arg_bool_slow(const zval *arg, uint32_t arg_num);
21962206
ZEND_API zend_string * ZEND_FASTCALL zend_flf_parse_arg_str_slow(zval *arg, uint32_t arg_num);
21972207
ZEND_API zend_opt_long ZEND_FASTCALL zend_flf_parse_arg_long_slow(const zval *arg, uint32_t arg_num);
21982208

@@ -2209,10 +2219,16 @@ static zend_always_inline bool zend_parse_arg_bool_ex(const zval *arg, bool *des
22092219
*is_null = 1;
22102220
*dest = 0;
22112221
} else {
2222+
zend_opt_bool result;
22122223
if (frameless) {
2213-
return zend_flf_parse_arg_bool_slow(arg, dest, arg_num);
2224+
result = zend_flf_parse_arg_bool_slow(arg, arg_num);
2225+
} else {
2226+
result = zend_parse_arg_bool_slow(arg, arg_num);
2227+
}
2228+
if (result.has_value) {
2229+
*dest = result.value;
22142230
} else {
2215-
return zend_parse_arg_bool_slow(arg, dest, arg_num);
2231+
return 0;
22162232
}
22172233
}
22182234
return 1;
@@ -2265,7 +2281,12 @@ static zend_always_inline bool zend_parse_arg_double(const zval *arg, double *de
22652281
*is_null = 1;
22662282
*dest = 0.0;
22672283
} else {
2268-
return zend_parse_arg_double_slow(arg, dest, arg_num);
2284+
zend_opt_double result = zend_parse_arg_double_slow(arg, arg_num);
2285+
if (result.has_value) {
2286+
*dest = result.value;
2287+
} else {
2288+
return 0;
2289+
}
22692290
}
22702291
return 1;
22712292
}

Zend/zend_execute.c

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -725,7 +725,6 @@ static bool zend_verify_weak_scalar_type_hint(uint32_t type_mask, zval *arg)
725725
{
726726
zend_long lval;
727727
double dval;
728-
bool bval;
729728

730729
/* Type preference order: int -> float -> string -> bool */
731730
if (type_mask & MAY_BE_LONG) {
@@ -754,19 +753,25 @@ static bool zend_verify_weak_scalar_type_hint(uint32_t type_mask, zval *arg)
754753
}
755754
}
756755
}
757-
if ((type_mask & MAY_BE_DOUBLE) && zend_parse_arg_double_weak(arg, &dval, 0)) {
758-
zval_ptr_dtor(arg);
759-
ZVAL_DOUBLE(arg, dval);
760-
return 1;
756+
if ((type_mask & MAY_BE_DOUBLE)) {
757+
zend_opt_double result = zend_parse_arg_double_weak(arg, 0);
758+
if (result.has_value) {
759+
zval_ptr_dtor(arg);
760+
ZVAL_DOUBLE(arg, dval);
761+
return 1;
762+
}
761763
}
762764
if ((type_mask & MAY_BE_STRING) && zend_parse_arg_str_weak(arg, 0)) {
763765
/* on success "arg" is converted to IS_STRING */
764766
return 1;
765767
}
766-
if ((type_mask & MAY_BE_BOOL) == MAY_BE_BOOL && zend_parse_arg_bool_weak(arg, &bval, 0)) {
767-
zval_ptr_dtor(arg);
768-
ZVAL_BOOL(arg, bval);
769-
return 1;
768+
if ((type_mask & MAY_BE_BOOL) == MAY_BE_BOOL) {
769+
zend_opt_bool result = zend_parse_arg_bool_weak(arg, 0);
770+
if (result.has_value) {
771+
zval_ptr_dtor(arg);
772+
ZVAL_BOOL(arg, result.value);
773+
return 1;
774+
}
770775
}
771776
return 0;
772777
}
@@ -786,21 +791,18 @@ static bool can_convert_to_string(const zval *zv) {
786791
/* Used to sanity-check internal arginfo types without performing any actual type conversions. */
787792
static bool zend_verify_weak_scalar_type_hint_no_sideeffect(uint32_t type_mask, const zval *arg)
788793
{
789-
double dval;
790-
bool bval;
791-
792794
/* Pass (uint32_t)-1 as arg_num to indicate to ZPP not to emit any deprecation notice,
793795
* this is needed because the version with side effects also uses 0 (e.g. for typed properties) */
794796
if ((type_mask & MAY_BE_LONG) && zend_parse_arg_long_weak(arg, (uint32_t)-1).has_value) {
795797
return 1;
796798
}
797-
if ((type_mask & MAY_BE_DOUBLE) && zend_parse_arg_double_weak(arg, &dval, (uint32_t)-1)) {
799+
if ((type_mask & MAY_BE_DOUBLE) && zend_parse_arg_double_weak(arg, (uint32_t)-1).has_value) {
798800
return 1;
799801
}
800802
if ((type_mask & MAY_BE_STRING) && can_convert_to_string(arg)) {
801803
return 1;
802804
}
803-
if ((type_mask & MAY_BE_BOOL) == MAY_BE_BOOL && zend_parse_arg_bool_weak(arg, &bval, (uint32_t)-1)) {
805+
if ((type_mask & MAY_BE_BOOL) == MAY_BE_BOOL && zend_parse_arg_bool_weak(arg, (uint32_t)-1).has_value) {
804806
return 1;
805807
}
806808
return 0;

0 commit comments

Comments
 (0)