Skip to content

Commit 41e3fdb

Browse files
Make zend_parse_parameters share fast zpp implementation where possible
Rename shared implementation functions and build them unconditionally Don't fail on empty path for zend_parse_arg_path Update type names Fix behaviour of by-reference "z" Make 'o' use zend_parse_arg_object Fix NULL string check in zend_parse_arg_path(_str)
1 parent cd5ea16 commit 41e3fdb

File tree

2 files changed

+94
-261
lines changed

2 files changed

+94
-261
lines changed

Zend/zend_API.c

Lines changed: 48 additions & 215 deletions
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ ZEND_API void zend_wrong_callback_error(int severity, int num, char *error) /* {
325325
}
326326
/* }}} */
327327

328-
ZEND_API int _z_param_class(zval *arg, zend_class_entry **pce, int num, int check_null) /* {{{ */
328+
ZEND_API int zend_parse_arg_class(zval *arg, zend_class_entry **pce, int num, int check_null) /* {{{ */
329329
{
330330
zend_class_entry *ce_base = *pce;
331331

@@ -387,265 +387,113 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons
387387
case 'L':
388388
{
389389
zend_long *p = va_arg(*va, zend_long *);
390+
zend_bool *is_null = NULL;
390391

391392
if (check_null) {
392-
zend_bool *p = va_arg(*va, zend_bool *);
393-
*p = (Z_TYPE_P(arg) == IS_NULL);
393+
is_null = va_arg(*va, zend_bool *);
394394
}
395395

396-
switch (Z_TYPE_P(arg)) {
397-
case IS_STRING:
398-
{
399-
double d;
400-
int type;
401-
402-
if ((type = is_numeric_string(Z_STRVAL_P(arg), Z_STRLEN_P(arg), p, &d, -1)) == 0) {
403-
return "integer";
404-
} else if (type == IS_DOUBLE) {
405-
if (zend_isnan(d)) {
406-
return "integer";
407-
}
408-
if (!ZEND_DOUBLE_FITS_LONG(d)) {
409-
if (c == 'L') {
410-
*p = (d > 0) ? ZEND_LONG_MAX : ZEND_LONG_MIN;
411-
} else {
412-
return "integer";
413-
}
414-
break;
415-
}
416-
417-
*p = zend_dval_to_lval(d);
418-
}
419-
}
420-
break;
421-
422-
case IS_DOUBLE:
423-
if (zend_isnan(Z_DVAL_P(arg))) {
424-
return "integer";
425-
}
426-
if (!ZEND_DOUBLE_FITS_LONG(Z_DVAL_P(arg))) {
427-
if (c == 'L') {
428-
*p = (Z_DVAL_P(arg) > 0) ? ZEND_LONG_MAX : ZEND_LONG_MIN;
429-
} else {
430-
return "integer";
431-
}
432-
break;
433-
}
434-
case IS_NULL:
435-
case IS_FALSE:
436-
case IS_TRUE:
437-
case IS_LONG:
438-
convert_to_long_ex(arg);
439-
*p = Z_LVAL_P(arg);
440-
break;
441-
442-
case IS_ARRAY:
443-
case IS_OBJECT:
444-
case IS_RESOURCE:
445-
default:
446-
return "integer";
396+
if (!zend_parse_arg_long(arg, p, is_null, check_null, c == 'L')) {
397+
return "integer";
447398
}
448399
}
449400
break;
450401

451402
case 'd':
452403
{
453404
double *p = va_arg(*va, double *);
405+
zend_bool *is_null = NULL;
454406

455407
if (check_null) {
456-
zend_bool *p = va_arg(*va, zend_bool *);
457-
*p = (Z_TYPE_P(arg) == IS_NULL);
408+
is_null = va_arg(*va, zend_bool *);
458409
}
459410

460-
switch (Z_TYPE_P(arg)) {
461-
case IS_STRING:
462-
{
463-
zend_long l;
464-
int type;
465-
466-
if ((type = is_numeric_string(Z_STRVAL_P(arg), Z_STRLEN_P(arg), &l, p, -1)) == 0) {
467-
return "float";
468-
} else if (type == IS_LONG) {
469-
*p = (double) l;
470-
}
471-
}
472-
break;
473-
474-
case IS_NULL:
475-
case IS_FALSE:
476-
case IS_TRUE:
477-
case IS_LONG:
478-
case IS_DOUBLE:
479-
convert_to_double_ex(arg);
480-
*p = Z_DVAL_P(arg);
481-
break;
482-
483-
case IS_ARRAY:
484-
case IS_OBJECT:
485-
case IS_RESOURCE:
486-
default:
487-
return "float";
411+
if (!zend_parse_arg_double(arg, p, is_null, check_null)) {
412+
return "float";
488413
}
489414
}
490415
break;
491416

492-
case 'p':
493417
case 's':
494418
{
495419
char **p = va_arg(*va, char **);
496420
size_t *pl = va_arg(*va, size_t *);
497-
switch (Z_TYPE_P(arg)) {
498-
case IS_NULL:
499-
if (check_null) {
500-
*p = NULL;
501-
*pl = 0;
502-
break;
503-
}
504-
/* break omitted intentionally */
505-
506-
case IS_LONG:
507-
case IS_DOUBLE:
508-
case IS_FALSE:
509-
case IS_TRUE:
510-
convert_to_string_ex(arg);
511-
case IS_STRING:
512-
*p = Z_STRVAL_P(arg);
513-
*pl = Z_STRLEN_P(arg);
514-
if (c == 'p' && CHECK_ZVAL_NULL_PATH(arg)) {
515-
return "a valid path";
516-
}
517-
break;
518-
519-
case IS_OBJECT:
520-
if (parse_arg_object_to_string(arg, p, pl, IS_STRING) == SUCCESS) {
521-
if (c == 'p' && CHECK_ZVAL_NULL_PATH(arg)) {
522-
return "a valid path";
523-
}
524-
break;
525-
}
526-
527-
case IS_ARRAY:
528-
case IS_RESOURCE:
529-
default:
530-
return c == 's' ? "string" : "a valid path";
421+
if (!zend_parse_arg_string(arg, p, pl, check_null)) {
422+
return "string";
423+
}
424+
}
425+
break;
426+
427+
case 'p':
428+
{
429+
char **p = va_arg(*va, char **);
430+
size_t *pl = va_arg(*va, size_t *);
431+
if (!zend_parse_arg_path(arg, p, pl, check_null)) {
432+
return "a valid path";
531433
}
532434
}
533435
break;
534436

535437
case 'P':
536-
case 'S':
537438
{
538439
zend_string **str = va_arg(*va, zend_string **);
539-
switch (Z_TYPE_P(arg)) {
540-
case IS_NULL:
541-
if (check_null) {
542-
*str = NULL;
543-
break;
544-
}
545-
/* break omitted intentionally */
546-
547-
case IS_LONG:
548-
case IS_DOUBLE:
549-
case IS_FALSE:
550-
case IS_TRUE:
551-
convert_to_string_ex(arg);
552-
case IS_STRING:
553-
*str = Z_STR_P(arg);
554-
if (c == 'P' && CHECK_ZVAL_NULL_PATH(arg)) {
555-
return "a valid path";
556-
}
557-
break;
440+
if (!zend_parse_arg_path_str(arg, str, check_null)) {
441+
return "a valid path";
442+
}
443+
}
444+
break;
558445

559-
case IS_OBJECT: {
560-
if (parse_arg_object_to_str(arg, str, IS_STRING) == SUCCESS) {
561-
if (c == 'P' && CHECK_ZVAL_NULL_PATH(arg)) {
562-
return "a valid path";
563-
}
564-
break;
565-
}
566-
}
567-
case IS_ARRAY:
568-
case IS_RESOURCE:
569-
default:
570-
return c == 'S' ? "string" : "a valid path";
446+
case 'S':
447+
{
448+
zend_string **str = va_arg(*va, zend_string **);
449+
if (!zend_parse_arg_str(arg, str, check_null)) {
450+
return "string";
571451
}
572452
}
573453
break;
574454

575455
case 'b':
576456
{
577457
zend_bool *p = va_arg(*va, zend_bool *);
458+
zend_bool *is_null = NULL;
578459

579460
if (check_null) {
580-
zend_bool *p = va_arg(*va, zend_bool *);
581-
*p = (Z_TYPE_P(arg) == IS_NULL);
461+
is_null = va_arg(*va, zend_bool *);
582462
}
583463

584-
switch (Z_TYPE_P(arg)) {
585-
case IS_NULL:
586-
case IS_STRING:
587-
case IS_LONG:
588-
case IS_DOUBLE:
589-
case IS_FALSE:
590-
case IS_TRUE:
591-
convert_to_boolean_ex(arg);
592-
*p = Z_TYPE_P(arg) == IS_TRUE;
593-
break;
594-
595-
case IS_ARRAY:
596-
case IS_OBJECT:
597-
case IS_RESOURCE:
598-
default:
599-
return "boolean";
464+
if (!zend_parse_arg_bool(arg, p, is_null, check_null)) {
465+
return "boolean";
600466
}
601467
}
602468
break;
603469

604470
case 'r':
605471
{
606472
zval **p = va_arg(*va, zval **);
607-
if (check_null && Z_TYPE_P(arg) == IS_NULL) {
608-
*p = NULL;
609-
break;
610-
}
611-
if (Z_TYPE_P(arg) == IS_RESOURCE) {
612-
*p = arg;
613-
} else {
473+
474+
if (!zend_parse_arg_resource(arg, p, check_null)) {
614475
return "resource";
615476
}
616477
}
617478
break;
479+
618480
case 'A':
619481
case 'a':
620482
{
621483
zval **p = va_arg(*va, zval **);
622-
if (check_null && Z_TYPE_P(arg) == IS_NULL) {
623-
*p = NULL;
624-
break;
625-
}
626-
if (Z_TYPE_P(arg) == IS_ARRAY || (c == 'A' && Z_TYPE_P(arg) == IS_OBJECT)) {
627-
*p = arg;
628-
} else {
484+
485+
if (!zend_parse_arg_array(arg, p, check_null, c == 'A')) {
629486
return "array";
630487
}
631488
}
632489
break;
490+
633491
case 'H':
634492
case 'h':
635493
{
636494
HashTable **p = va_arg(*va, HashTable **);
637-
if (check_null && Z_TYPE_P(arg) == IS_NULL) {
638-
*p = NULL;
639-
break;
640-
}
641-
if (Z_TYPE_P(arg) == IS_ARRAY) {
642-
*p = Z_ARRVAL_P(arg);
643-
} else if(c == 'H' && Z_TYPE_P(arg) == IS_OBJECT) {
644-
*p = HASH_OF(arg);
645-
if(*p == NULL) {
646-
return "array";
647-
}
648-
} else {
495+
496+
if (!zend_parse_arg_array_ht(arg, p, check_null, c == 'H')) {
649497
return "array";
650498
}
651499
}
@@ -654,13 +502,8 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons
654502
case 'o':
655503
{
656504
zval **p = va_arg(*va, zval **);
657-
if (check_null && Z_TYPE_P(arg) == IS_NULL) {
658-
*p = NULL;
659-
break;
660-
}
661-
if (Z_TYPE_P(arg) == IS_OBJECT) {
662-
*p = arg;
663-
} else {
505+
506+
if (!zend_parse_arg_object(arg, p, NULL, check_null)) {
664507
return "object";
665508
}
666509
}
@@ -671,14 +514,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons
671514
zval **p = va_arg(*va, zval **);
672515
zend_class_entry *ce = va_arg(*va, zend_class_entry *);
673516

674-
if (check_null && Z_TYPE_P(arg) == IS_NULL) {
675-
*p = NULL;
676-
break;
677-
}
678-
if (Z_TYPE_P(arg) == IS_OBJECT &&
679-
(!ce || instanceof_function(Z_OBJCE_P(arg), ce))) {
680-
*p = arg;
681-
} else {
517+
if (!zend_parse_arg_object(arg, p, ce, check_null)) {
682518
if (ce) {
683519
return ce->name->val;
684520
} else {
@@ -757,11 +593,8 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons
757593
case 'z':
758594
{
759595
zval **p = va_arg(*va, zval **);
760-
if (check_null && Z_TYPE_P(arg) == IS_NULL) {
761-
*p = NULL;
762-
} else {
763-
*p = real_arg;
764-
}
596+
597+
zend_parse_arg_zval_deref(real_arg, p, check_null);
765598
}
766599
break;
767600

0 commit comments

Comments
 (0)