@@ -87,6 +87,7 @@ ZEND_API zend_executor_globals executor_globals;
87
87
#endif
88
88
89
89
static zend_op * zend_emit_op (znode * result , zend_uchar opcode , znode * op1 , znode * op2 );
90
+ static zend_bool zend_try_ct_eval_array (zval * result , zend_ast * ast );
90
91
91
92
static void zend_destroy_property_info_internal (zval * zv ) /* {{{ */
92
93
{
@@ -2224,6 +2225,7 @@ ZEND_API int zend_is_smart_branch(zend_op *opline) /* {{{ */
2224
2225
case ZEND_INSTANCEOF :
2225
2226
case ZEND_TYPE_CHECK :
2226
2227
case ZEND_DEFINED :
2228
+ case ZEND_IN_ARRAY :
2227
2229
return 1 ;
2228
2230
default :
2229
2231
return 0 ;
@@ -3635,6 +3637,76 @@ static int zend_compile_assert(znode *result, zend_ast_list *args, zend_string *
3635
3637
}
3636
3638
/* }}} */
3637
3639
3640
+ static int zend_compile_func_in_array (znode * result , zend_ast_list * args ) /* {{{ */
3641
+ {
3642
+ zend_bool strict = 0 ;
3643
+ znode array , needly ;
3644
+ zend_op * opline ;
3645
+
3646
+ if (args -> children == 3 ) {
3647
+ if (args -> child [2 ]-> kind != ZEND_AST_ZVAL ) {
3648
+ return FAILURE ;
3649
+ }
3650
+ strict = zend_is_true (zend_ast_get_zval (args -> child [2 ]));
3651
+ }
3652
+
3653
+ if (args -> children < 2
3654
+ || args -> children > 3
3655
+ || args -> child [1 ]-> kind != ZEND_AST_ARRAY
3656
+ || !zend_try_ct_eval_array (& array .u .constant , args -> child [1 ])) {
3657
+ return FAILURE ;
3658
+ }
3659
+
3660
+ if (zend_hash_num_elements (Z_ARRVAL (array .u .constant )) > 0 ) {
3661
+ zend_bool ok = 1 ;
3662
+ zval * val , tmp ;
3663
+ zend_ulong idx ;
3664
+ HashTable * src = Z_ARRVAL (array .u .constant );
3665
+ HashTable * dst = emalloc (sizeof (HashTable ));
3666
+
3667
+ zend_hash_init (dst , zend_hash_num_elements (src ), NULL , ZVAL_PTR_DTOR , 0 );
3668
+ ZVAL_TRUE (& tmp );
3669
+
3670
+ if (strict ) {
3671
+ ZEND_HASH_FOREACH_VAL (src , val ) {
3672
+ if (Z_TYPE_P (val ) == IS_STRING ) {
3673
+ zend_hash_add (dst , Z_STR_P (val ), & tmp );
3674
+ } else if (Z_TYPE_P (val ) == IS_LONG ) {
3675
+ zend_hash_index_add (dst , Z_LVAL_P (val ), & tmp );
3676
+ } else {
3677
+ zend_array_destroy (dst );
3678
+ ok = 0 ;
3679
+ break ;
3680
+ }
3681
+ } ZEND_HASH_FOREACH_END ();
3682
+ } else {
3683
+ ZEND_HASH_FOREACH_VAL (src , val ) {
3684
+ if (Z_TYPE_P (val ) != IS_STRING || ZEND_HANDLE_NUMERIC (Z_STR_P (val ), idx )) {
3685
+ zend_array_destroy (dst );
3686
+ ok = 0 ;
3687
+ break ;
3688
+ }
3689
+ zend_hash_add (dst , Z_STR_P (val ), & tmp );
3690
+ } ZEND_HASH_FOREACH_END ();
3691
+ }
3692
+
3693
+ zend_array_destroy (src );
3694
+ if (!ok ) {
3695
+ return FAILURE ;
3696
+ }
3697
+ Z_ARRVAL (array .u .constant ) = dst ;
3698
+ }
3699
+ array .op_type = IS_CONST ;
3700
+
3701
+ zend_compile_expr (& needly , args -> child [0 ]);
3702
+
3703
+ opline = zend_emit_op_tmp (result , ZEND_IN_ARRAY , & needly , & array );
3704
+ opline -> extended_value = strict ;
3705
+
3706
+ return SUCCESS ;
3707
+ }
3708
+ /* }}} */
3709
+
3638
3710
int zend_try_compile_special_func (znode * result , zend_string * lcname , zend_ast_list * args , zend_function * fbc , uint32_t type ) /* {{{ */
3639
3711
{
3640
3712
if (fbc -> internal_function .handler == ZEND_FN (display_disabled_function )) {
@@ -3693,6 +3765,8 @@ int zend_try_compile_special_func(znode *result, zend_string *lcname, zend_ast_l
3693
3765
return zend_compile_func_cufa (result , args , lcname );
3694
3766
} else if (zend_string_equals_literal (lcname , "call_user_func" )) {
3695
3767
return zend_compile_func_cuf (result , args , lcname );
3768
+ } else if (zend_string_equals_literal (lcname , "in_array" )) {
3769
+ return zend_compile_func_in_array (result , args );
3696
3770
} else {
3697
3771
return FAILURE ;
3698
3772
}
0 commit comments