@@ -498,17 +498,23 @@ zend_class_entry *zend_ast_fetch_class(zend_ast *ast, zend_class_entry *scope)
498498 return zend_fetch_class_with_scope (zend_ast_get_str (ast ), (ast -> attr >> ZEND_CONST_EXPR_NEW_FETCH_TYPE_SHIFT ) | ZEND_FETCH_CLASS_EXCEPTION , scope );
499499}
500500
501- ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_ex (zval * result , zend_ast * ast , zend_class_entry * scope , zend_ast_evaluate_ctx * ctx )
502- {
501+ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_ex (
502+ zval * result ,
503+ zend_ast * ast ,
504+ zend_class_entry * scope ,
505+ bool * short_circuited_ptr ,
506+ zend_ast_evaluate_ctx * ctx
507+ ) {
503508 zval op1 , op2 ;
504509 zend_result ret = SUCCESS ;
505- ctx -> short_circuited = false;
510+ bool short_circuited ;
511+ * short_circuited_ptr = false;
506512
507513 switch (ast -> kind ) {
508514 case ZEND_AST_BINARY_OP :
509- if (UNEXPECTED (zend_ast_evaluate_ex (& op1 , ast -> child [0 ], scope , ctx ) != SUCCESS )) {
515+ if (UNEXPECTED (zend_ast_evaluate_ex (& op1 , ast -> child [0 ], scope , & short_circuited , ctx ) != SUCCESS )) {
510516 ret = FAILURE ;
511- } else if (UNEXPECTED (zend_ast_evaluate_ex (& op2 , ast -> child [1 ], scope , ctx ) != SUCCESS )) {
517+ } else if (UNEXPECTED (zend_ast_evaluate_ex (& op2 , ast -> child [1 ], scope , & short_circuited , ctx ) != SUCCESS )) {
512518 zval_ptr_dtor_nogc (& op1 );
513519 ret = FAILURE ;
514520 } else {
@@ -520,9 +526,9 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *
520526 break ;
521527 case ZEND_AST_GREATER :
522528 case ZEND_AST_GREATER_EQUAL :
523- if (UNEXPECTED (zend_ast_evaluate_ex (& op1 , ast -> child [0 ], scope , ctx ) != SUCCESS )) {
529+ if (UNEXPECTED (zend_ast_evaluate_ex (& op1 , ast -> child [0 ], scope , & short_circuited , ctx ) != SUCCESS )) {
524530 ret = FAILURE ;
525- } else if (UNEXPECTED (zend_ast_evaluate_ex (& op2 , ast -> child [1 ], scope , ctx ) != SUCCESS )) {
531+ } else if (UNEXPECTED (zend_ast_evaluate_ex (& op2 , ast -> child [1 ], scope , & short_circuited , ctx ) != SUCCESS )) {
526532 zval_ptr_dtor_nogc (& op1 );
527533 ret = FAILURE ;
528534 } else {
@@ -535,7 +541,7 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *
535541 }
536542 break ;
537543 case ZEND_AST_UNARY_OP :
538- if (UNEXPECTED (zend_ast_evaluate_ex (& op1 , ast -> child [0 ], scope , ctx ) != SUCCESS )) {
544+ if (UNEXPECTED (zend_ast_evaluate_ex (& op1 , ast -> child [0 ], scope , & short_circuited , ctx ) != SUCCESS )) {
539545 ret = FAILURE ;
540546 } else {
541547 unary_op_type op = get_unary_op (ast -> attr );
@@ -588,12 +594,12 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *
588594 }
589595 break ;
590596 case ZEND_AST_AND :
591- if (UNEXPECTED (zend_ast_evaluate_ex (& op1 , ast -> child [0 ], scope , ctx ) != SUCCESS )) {
597+ if (UNEXPECTED (zend_ast_evaluate_ex (& op1 , ast -> child [0 ], scope , & short_circuited , ctx ) != SUCCESS )) {
592598 ret = FAILURE ;
593599 break ;
594600 }
595601 if (zend_is_true (& op1 )) {
596- if (UNEXPECTED (zend_ast_evaluate_ex (& op2 , ast -> child [1 ], scope , ctx ) != SUCCESS )) {
602+ if (UNEXPECTED (zend_ast_evaluate_ex (& op2 , ast -> child [1 ], scope , & short_circuited , ctx ) != SUCCESS )) {
597603 zval_ptr_dtor_nogc (& op1 );
598604 ret = FAILURE ;
599605 break ;
@@ -606,14 +612,14 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *
606612 zval_ptr_dtor_nogc (& op1 );
607613 break ;
608614 case ZEND_AST_OR :
609- if (UNEXPECTED (zend_ast_evaluate_ex (& op1 , ast -> child [0 ], scope , ctx ) != SUCCESS )) {
615+ if (UNEXPECTED (zend_ast_evaluate_ex (& op1 , ast -> child [0 ], scope , & short_circuited , ctx ) != SUCCESS )) {
610616 ret = FAILURE ;
611617 break ;
612618 }
613619 if (zend_is_true (& op1 )) {
614620 ZVAL_TRUE (result );
615621 } else {
616- if (UNEXPECTED (zend_ast_evaluate_ex (& op2 , ast -> child [1 ], scope , ctx ) != SUCCESS )) {
622+ if (UNEXPECTED (zend_ast_evaluate_ex (& op2 , ast -> child [1 ], scope , & short_circuited , ctx ) != SUCCESS )) {
617623 zval_ptr_dtor_nogc (& op1 );
618624 ret = FAILURE ;
619625 break ;
@@ -624,23 +630,23 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *
624630 zval_ptr_dtor_nogc (& op1 );
625631 break ;
626632 case ZEND_AST_CONDITIONAL :
627- if (UNEXPECTED (zend_ast_evaluate_ex (& op1 , ast -> child [0 ], scope , ctx ) != SUCCESS )) {
633+ if (UNEXPECTED (zend_ast_evaluate_ex (& op1 , ast -> child [0 ], scope , & short_circuited , ctx ) != SUCCESS )) {
628634 ret = FAILURE ;
629635 break ;
630636 }
631637 if (zend_is_true (& op1 )) {
632638 if (!ast -> child [1 ]) {
633639 * result = op1 ;
634640 } else {
635- if (UNEXPECTED (zend_ast_evaluate_ex (result , ast -> child [1 ], scope , ctx ) != SUCCESS )) {
641+ if (UNEXPECTED (zend_ast_evaluate_ex (result , ast -> child [1 ], scope , & short_circuited , ctx ) != SUCCESS )) {
636642 zval_ptr_dtor_nogc (& op1 );
637643 ret = FAILURE ;
638644 break ;
639645 }
640646 zval_ptr_dtor_nogc (& op1 );
641647 }
642648 } else {
643- if (UNEXPECTED (zend_ast_evaluate_ex (result , ast -> child [2 ], scope , ctx ) != SUCCESS )) {
649+ if (UNEXPECTED (zend_ast_evaluate_ex (result , ast -> child [2 ], scope , & short_circuited , ctx ) != SUCCESS )) {
644650 zval_ptr_dtor_nogc (& op1 );
645651 ret = FAILURE ;
646652 break ;
@@ -649,14 +655,14 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *
649655 }
650656 break ;
651657 case ZEND_AST_COALESCE :
652- if (UNEXPECTED (zend_ast_evaluate_ex (& op1 , ast -> child [0 ], scope , ctx ) != SUCCESS )) {
658+ if (UNEXPECTED (zend_ast_evaluate_ex (& op1 , ast -> child [0 ], scope , & short_circuited , ctx ) != SUCCESS )) {
653659 ret = FAILURE ;
654660 break ;
655661 }
656662 if (Z_TYPE (op1 ) > IS_NULL ) {
657663 * result = op1 ;
658664 } else {
659- if (UNEXPECTED (zend_ast_evaluate_ex (result , ast -> child [1 ], scope , ctx ) != SUCCESS )) {
665+ if (UNEXPECTED (zend_ast_evaluate_ex (result , ast -> child [1 ], scope , & short_circuited , ctx ) != SUCCESS )) {
660666 zval_ptr_dtor_nogc (& op1 );
661667 ret = FAILURE ;
662668 break ;
@@ -665,7 +671,7 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *
665671 }
666672 break ;
667673 case ZEND_AST_UNARY_PLUS :
668- if (UNEXPECTED (zend_ast_evaluate_ex (& op2 , ast -> child [0 ], scope , ctx ) != SUCCESS )) {
674+ if (UNEXPECTED (zend_ast_evaluate_ex (& op2 , ast -> child [0 ], scope , & short_circuited , ctx ) != SUCCESS )) {
669675 ret = FAILURE ;
670676 } else {
671677 ZVAL_LONG (& op1 , 0 );
@@ -674,7 +680,7 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *
674680 }
675681 break ;
676682 case ZEND_AST_UNARY_MINUS :
677- if (UNEXPECTED (zend_ast_evaluate_ex (& op2 , ast -> child [0 ], scope , ctx ) != SUCCESS )) {
683+ if (UNEXPECTED (zend_ast_evaluate_ex (& op2 , ast -> child [0 ], scope , & short_circuited , ctx ) != SUCCESS )) {
678684 ret = FAILURE ;
679685 } else {
680686 ZVAL_LONG (& op1 , 0 );
@@ -695,7 +701,7 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *
695701 for (i = 0 ; i < list -> children ; i ++ ) {
696702 zend_ast * elem = list -> child [i ];
697703 if (elem -> kind == ZEND_AST_UNPACK ) {
698- if (UNEXPECTED (zend_ast_evaluate_ex (& op1 , elem -> child [0 ], scope , ctx ) != SUCCESS )) {
704+ if (UNEXPECTED (zend_ast_evaluate_ex (& op1 , elem -> child [0 ], scope , & short_circuited , ctx ) != SUCCESS )) {
699705 zval_ptr_dtor_nogc (result );
700706 return FAILURE ;
701707 }
@@ -708,14 +714,14 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *
708714 continue ;
709715 }
710716 if (elem -> child [1 ]) {
711- if (UNEXPECTED (zend_ast_evaluate_ex (& op1 , elem -> child [1 ], scope , ctx ) != SUCCESS )) {
717+ if (UNEXPECTED (zend_ast_evaluate_ex (& op1 , elem -> child [1 ], scope , & short_circuited , ctx ) != SUCCESS )) {
712718 zval_ptr_dtor_nogc (result );
713719 return FAILURE ;
714720 }
715721 } else {
716722 ZVAL_UNDEF (& op1 );
717723 }
718- if (UNEXPECTED (zend_ast_evaluate_ex (& op2 , elem -> child [0 ], scope , ctx ) != SUCCESS )) {
724+ if (UNEXPECTED (zend_ast_evaluate_ex (& op2 , elem -> child [0 ], scope , & short_circuited , ctx ) != SUCCESS )) {
719725 zval_ptr_dtor_nogc (& op1 );
720726 zval_ptr_dtor_nogc (result );
721727 return FAILURE ;
@@ -734,11 +740,12 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *
734740 zend_error_noreturn (E_COMPILE_ERROR , "Cannot use [] for reading" );
735741 }
736742
737- if (UNEXPECTED (zend_ast_evaluate_ex (& op1 , ast -> child [0 ], scope , ctx ) != SUCCESS )) {
743+ if (UNEXPECTED (zend_ast_evaluate_ex (& op1 , ast -> child [0 ], scope , & short_circuited , ctx ) != SUCCESS )) {
738744 ret = FAILURE ;
739745 break ;
740746 }
741- if (ctx -> short_circuited ) {
747+ if (short_circuited ) {
748+ * short_circuited_ptr = true;
742749 ZVAL_NULL (result );
743750 return SUCCESS ;
744751 }
@@ -751,7 +758,7 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *
751758 break ;
752759 }
753760
754- if (UNEXPECTED (zend_ast_evaluate_ex (& op2 , ast -> child [1 ], scope , ctx ) != SUCCESS )) {
761+ if (UNEXPECTED (zend_ast_evaluate_ex (& op2 , ast -> child [1 ], scope , & short_circuited , ctx ) != SUCCESS )) {
755762 zval_ptr_dtor_nogc (& op1 );
756763 ret = FAILURE ;
757764 break ;
@@ -785,7 +792,7 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *
785792 zval case_value_zv ;
786793 ZVAL_UNDEF (& case_value_zv );
787794 if (case_value_ast != NULL ) {
788- if (UNEXPECTED (zend_ast_evaluate_ex (& case_value_zv , case_value_ast , scope , ctx ) != SUCCESS )) {
795+ if (UNEXPECTED (zend_ast_evaluate_ex (& case_value_zv , case_value_ast , scope , & short_circuited , ctx ) != SUCCESS )) {
789796 return FAILURE ;
790797 }
791798 }
@@ -847,7 +854,7 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *
847854 name = zend_ast_get_str (arg_ast -> child [0 ]);
848855 arg_ast = arg_ast -> child [1 ];
849856 }
850- if (zend_ast_evaluate_ex (& arg , arg_ast , scope , ctx ) == FAILURE ) {
857+ if (zend_ast_evaluate_ex (& arg , arg_ast , scope , & short_circuited , ctx ) == FAILURE ) {
851858 zend_array_destroy (args );
852859 zval_ptr_dtor (result );
853860 return FAILURE ;
@@ -877,7 +884,7 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *
877884 ALLOCA_FLAG (use_heap )
878885 zval * args = do_alloca (sizeof (zval ) * args_ast -> children , use_heap );
879886 for (uint32_t i = 0 ; i < args_ast -> children ; i ++ ) {
880- if (zend_ast_evaluate_ex (& args [i ], args_ast -> child [i ], scope , ctx ) == FAILURE ) {
887+ if (zend_ast_evaluate_ex (& args [i ], args_ast -> child [i ], scope , & short_circuited , ctx ) == FAILURE ) {
881888 for (uint32_t j = 0 ; j < i ; j ++ ) {
882889 zval_ptr_dtor (& args [j ]);
883890 }
@@ -909,20 +916,21 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *
909916 case ZEND_AST_PROP :
910917 case ZEND_AST_NULLSAFE_PROP :
911918 {
912- if (UNEXPECTED (zend_ast_evaluate_ex (& op1 , ast -> child [0 ], scope , ctx ) != SUCCESS )) {
919+ if (UNEXPECTED (zend_ast_evaluate_ex (& op1 , ast -> child [0 ], scope , & short_circuited , ctx ) != SUCCESS )) {
913920 return FAILURE ;
914921 }
915- if (ctx -> short_circuited ) {
922+ if (short_circuited ) {
923+ * short_circuited_ptr = true;
916924 ZVAL_NULL (result );
917925 return SUCCESS ;
918926 }
919927 if (ast -> kind == ZEND_AST_NULLSAFE_PROP && Z_TYPE (op1 ) == IS_NULL ) {
920- ctx -> short_circuited = true;
928+ * short_circuited_ptr = true;
921929 ZVAL_NULL (result );
922930 return SUCCESS ;
923931 }
924932
925- if (UNEXPECTED (zend_ast_evaluate_ex (& op2 , ast -> child [1 ], scope , ctx ) != SUCCESS )) {
933+ if (UNEXPECTED (zend_ast_evaluate_ex (& op2 , ast -> child [1 ], scope , & short_circuited , ctx ) != SUCCESS )) {
926934 zval_ptr_dtor_nogc (& op1 );
927935 return FAILURE ;
928936 }
@@ -976,7 +984,8 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *
976984ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate (zval * result , zend_ast * ast , zend_class_entry * scope )
977985{
978986 zend_ast_evaluate_ctx ctx = {0 };
979- return zend_ast_evaluate_ex (result , ast , scope , & ctx );
987+ bool short_circuited ;
988+ return zend_ast_evaluate_ex (result , ast , scope , & short_circuited , & ctx );
980989}
981990
982991static size_t ZEND_FASTCALL zend_ast_tree_size (zend_ast * ast )
0 commit comments