@@ -702,6 +702,71 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_inner(
702702 }
703703 zval_ptr_dtor_nogc (& op1 );
704704 break ;
705+ case ZEND_AST_CAST :
706+ if (UNEXPECTED (zend_ast_evaluate_ex (& op1 , ast -> child [0 ], scope , & short_circuited , ctx ) != SUCCESS )) {
707+ ret = FAILURE ;
708+ break ;
709+ }
710+ if (ast -> attr == Z_TYPE (op1 )) {
711+ ZVAL_COPY_VALUE (result , & op1 );
712+ } else {
713+ switch (ast -> attr ) {
714+ case _IS_BOOL :
715+ ZVAL_BOOL (result , zend_is_true (& op1 ));
716+ zval_ptr_dtor_nogc (& op1 );
717+ break ;
718+ case IS_LONG :
719+ ZVAL_LONG (result , zval_get_long_func (& op1 , false));
720+ zval_ptr_dtor_nogc (& op1 );
721+ break ;
722+ case IS_DOUBLE :
723+ ZVAL_DOUBLE (result , zval_get_double_func (& op1 ));
724+ zval_ptr_dtor_nogc (& op1 );
725+ break ;
726+ case IS_STRING :
727+ ZVAL_STR (result , zval_get_string_func (& op1 ));
728+ zval_ptr_dtor_nogc (& op1 );
729+ break ;
730+ case IS_ARRAY :
731+ /* Adapted from VM */
732+ if (Z_TYPE (op1 ) != IS_OBJECT || Z_OBJCE (op1 ) == zend_ce_closure ) {
733+ if (Z_TYPE (op1 ) != IS_NULL ) {
734+ ZVAL_ARR (result , zend_new_array (1 ));
735+ zend_hash_index_add_new (Z_ARRVAL_P (result ), 0 , & op1 );
736+ } else {
737+ ZVAL_EMPTY_ARRAY (result );
738+ }
739+ } else {
740+ /* Constant AST only allows building stdClass objects, closures, or user classes;
741+ * all of which should be compatible. */
742+ ZEND_ASSERT (ZEND_STD_BUILD_OBJECT_PROPERTIES_ARRAY_COMPATIBLE (& op1 ));
743+
744+ /* Optimized version without rebuilding properties HashTable */
745+ ZVAL_ARR (result , zend_std_build_object_properties_array (Z_OBJ (op1 )));
746+ zval_ptr_dtor_nogc (& op1 );
747+ }
748+ break ;
749+ case IS_OBJECT :
750+ /* Adapted from VM */
751+ ZVAL_OBJ (result , zend_objects_new (zend_standard_class_def ));
752+ if (Z_TYPE (op1 ) == IS_ARRAY ) {
753+ HashTable * ht = zend_symtable_to_proptable (Z_ARR (op1 ));
754+ if (GC_FLAGS (ht ) & IS_ARRAY_IMMUTABLE ) {
755+ /* TODO: try not to duplicate immutable arrays as well ??? */
756+ ht = zend_array_dup (ht );
757+ }
758+ Z_OBJ_P (result )-> properties = ht ;
759+ zval_ptr_dtor_nogc (& op1 );
760+ } else if (Z_TYPE (op1 ) != IS_NULL ) {
761+ HashTable * ht = zend_new_array (1 );
762+ Z_OBJ_P (result )-> properties = ht ;
763+ zend_hash_add_new (ht , ZSTR_KNOWN (ZEND_STR_SCALAR ), & op1 );
764+ }
765+ break ;
766+ EMPTY_SWITCH_DEFAULT_CASE ();
767+ }
768+ }
769+ break ;
705770 case ZEND_AST_OR :
706771 if (UNEXPECTED (zend_ast_evaluate_ex (& op1 , ast -> child [0 ], scope , & short_circuited , ctx ) != SUCCESS )) {
707772 ret = FAILURE ;
0 commit comments