@@ -107,6 +107,11 @@ static const char *class_flags[] = {
107
107
static const char * param_flags [] = {
108
108
AST_FLAG (PARAM_REF ),
109
109
AST_FLAG (PARAM_VARIADIC ),
110
+ #if PHP_VERSION_ID >= 80000
111
+ AST_FLAG (MODIFIER_PUBLIC ),
112
+ AST_FLAG (MODIFIER_PROTECTED ),
113
+ AST_FLAG (MODIFIER_PRIVATE ),
114
+ #endif
110
115
NULL
111
116
};
112
117
@@ -287,6 +292,8 @@ static const ast_flag_info flag_info[] = {
287
292
{ ZEND_AST_CONDITIONAL , 1 , conditional_flags },
288
293
};
289
294
295
+ // NOTE(tandre) in php 8, to get a writeable pointer to a property, OBJ_PROP_NUM(AST_CACHE_SLOT_PROPNAME) can be used.
296
+
290
297
static inline void ast_update_property (zval * object , zend_string * name , zval * value , void * * cache_slot ) {
291
298
#if PHP_VERSION_ID < 80000
292
299
zval name_zv ;
@@ -339,6 +346,7 @@ static zend_ast *get_ast(zend_string *code, zend_arena **ast_arena, char *filena
339
346
return ast ;
340
347
}
341
348
349
+ /* Returns whether node->attr (i.e. flags) is used by this node kind. Not to be confused with php 8.0's attributes. */
342
350
static inline zend_bool ast_kind_uses_attr (zend_ast_kind kind ) {
343
351
return kind == ZEND_AST_PARAM || kind == ZEND_AST_TYPE || kind == ZEND_AST_TRAIT_ALIAS
344
352
|| kind == ZEND_AST_UNARY_OP || kind == ZEND_AST_BINARY_OP || kind == ZEND_AST_ASSIGN_OP
@@ -380,6 +388,9 @@ static inline zend_bool ast_is_name(zend_ast *ast, zend_ast *parent, uint32_t i)
380
388
|| parent -> kind == ZEND_AST_NEW || parent -> kind == ZEND_AST_STATIC_CALL
381
389
|| parent -> kind == ZEND_AST_CLASS_CONST || parent -> kind == ZEND_AST_STATIC_PROP
382
390
|| parent -> kind == ZEND_AST_PROP_GROUP || parent -> kind == ZEND_AST_CLASS_NAME
391
+ #if PHP_VERSION_ID >= 80000
392
+ || parent -> kind == ZEND_AST_ATTRIBUTE
393
+ #endif
383
394
;
384
395
}
385
396
@@ -507,7 +518,11 @@ static inline zend_ast_attr ast_assign_op_to_binary_op(zend_ast_attr attr) {
507
518
static inline zend_ast * * ast_get_children (zend_ast * ast , uint32_t * count ) {
508
519
if (ast_kind_is_decl (ast -> kind )) {
509
520
zend_ast_decl * decl = (zend_ast_decl * ) ast ;
521
+ #if PHP_VERSION_ID >= 80000
522
+ * count = decl -> kind == ZEND_AST_CLASS ? 4 : 5 ;
523
+ #else
510
524
* count = decl -> kind == ZEND_AST_CLASS ? 3 : 4 ;
525
+ #endif
511
526
return decl -> child ;
512
527
} else if (zend_ast_is_list (ast )) {
513
528
zend_ast_list * list = zend_ast_get_list (ast );
@@ -622,14 +637,44 @@ static void ast_fill_children_ht(HashTable *ht, zend_ast *ast, ast_state_info_t
622
637
}
623
638
}
624
639
640
+ #if PHP_VERSION_ID >= 80000
641
+ if (state -> version < 80 ) {
642
+ switch (ast_kind ) {
643
+ case ZEND_AST_PARAM :
644
+ if (i >= 3 ) {
645
+ /* Skip attributes and doc comment */
646
+ continue ;
647
+ }
648
+ break ;
649
+ case ZEND_AST_METHOD :
650
+ case ZEND_AST_FUNC_DECL :
651
+ case ZEND_AST_CLOSURE :
652
+ case ZEND_AST_ARROW_FUNC :
653
+ if (i == 4 ) {
654
+ continue ;
655
+ }
656
+ break ;
657
+ case ZEND_AST_CLASS :
658
+ if (i == 3 ) {
659
+ continue ;
660
+ }
661
+ break ;
662
+ case ZEND_AST_PROP_GROUP :
663
+ if (i == 2 ) {
664
+ continue ;
665
+ }
666
+ break ;
667
+ }
668
+ }
669
+ #endif
625
670
/* This AST_CATCH check should occur before ast_is_name() */
626
671
#if PHP_VERSION_ID < 70100
627
672
if (ast_kind == ZEND_AST_CATCH && i == 0 ) {
628
673
/* Emulate PHP 7.1 format (name list) */
629
674
zval tmp ;
630
675
ast_create_virtual_node (& tmp , AST_NAME , child -> attr , child , state );
631
676
ast_create_virtual_node_ex (
632
- & child_zv , ZEND_AST_NAME_LIST , 0 , zend_ast_get_lineno (child ), state , 1 , & tmp );
677
+ & child_zv , ZEND_AST_NAME_LIST , 0 , zend_ast_get_lineno (child ), state , 1 , & tmp );
633
678
} else
634
679
#endif
635
680
if (ast_is_name (child , ast , i )) {
@@ -693,11 +738,35 @@ static void ast_fill_children_ht(HashTable *ht, zend_ast *ast, ast_state_info_t
693
738
zval tmp ;
694
739
ZVAL_NULL (& tmp );
695
740
zend_hash_add_new (ht , AST_STR (str_docComment ), & tmp );
741
+ return ;
742
+ }
743
+ #endif
744
+ #if PHP_VERSION_ID < 80000
745
+ if (state -> version >= 80 ) {
746
+ if (ast_kind == ZEND_AST_PARAM ) {
747
+ zval tmp ;
748
+ ZVAL_NULL (& tmp );
749
+ zend_hash_add_new (ht , AST_STR (str_attributes ), & tmp );
750
+ zend_hash_add_new (ht , AST_STR (str_docComment ), & tmp );
751
+ return ;
752
+ } else if (ast_kind == ZEND_AST_PROP_GROUP ) {
753
+ zval tmp ;
754
+ ZVAL_NULL (& tmp );
755
+ zend_hash_add_new (ht , AST_STR (str_attributes ), & tmp );
756
+ return ;
757
+ }
696
758
}
697
759
#endif
698
760
699
761
if (ast_kind_is_decl (ast_kind )) {
700
762
zval id_zval ;
763
+ #if PHP_VERSION_ID < 80000
764
+ if (state -> version >= 80 ) {
765
+ zval tmp ;
766
+ ZVAL_NULL (& tmp );
767
+ zend_hash_add_new (ht , AST_STR (str_attributes ), & tmp );
768
+ }
769
+ #endif
701
770
ZVAL_LONG (& id_zval , state -> declIdCounter );
702
771
state -> declIdCounter ++ ;
703
772
zend_hash_add_new (ht , AST_STR (str___declId ), & id_zval );
@@ -755,6 +824,15 @@ static void ast_to_zval(zval *zv, zend_ast *ast, ast_state_info_t *state) {
755
824
ast -> kind = ZEND_AST_UNARY_OP ;
756
825
ast -> attr = AST_MINUS ;
757
826
break ;
827
+ #if PHP_VERSION_ID >= 80000
828
+ case ZEND_AST_CLASS_CONST_GROUP :
829
+ // ast->child is [AST_CLASS_CONST_DECL, optional attributes_list]
830
+ if (state -> version < 80 ) {
831
+ // Keep class constants as a list of numerically indexed values in php 8
832
+ ast_to_zval (zv , ast -> child [0 ], state );
833
+ return ;
834
+ }
835
+ #endif
758
836
#if PHP_VERSION_ID >= 70400
759
837
case ZEND_AST_PROP_GROUP :
760
838
if (state -> version < 70 ) {
@@ -876,14 +954,32 @@ static void ast_to_zval(zval *zv, zend_ast *ast, ast_state_info_t *state) {
876
954
#if PHP_VERSION_ID < 70400
877
955
if (ast -> kind == ZEND_AST_PROP_DECL && state -> version >= 70 ) {
878
956
zval type_zval ;
879
- zval prop_group_zval = * zv ;
957
+ zval prop_group_zval ;
958
+ ZVAL_COPY_VALUE (& prop_group_zval , zv );
880
959
ZVAL_NULL (& type_zval );
881
960
// For version 70, create an AST_PROP_GROUP wrapping the created AST_PROP_DECL.
882
- ast_create_virtual_node_ex (
883
- zv , ZEND_AST_PROP_GROUP , ast -> attr , zend_ast_get_lineno (ast ), state , 2 , & type_zval , & prop_group_zval );
961
+ if (state -> version >= 80 ) {
962
+ // For version 80, add a null attributes node.
963
+ ast_create_virtual_node_ex (
964
+ zv , ZEND_AST_PROP_GROUP , ast -> attr , zend_ast_get_lineno (ast ), state , 3 , & type_zval , & prop_group_zval , & type_zval );
965
+ } else {
966
+ ast_create_virtual_node_ex (
967
+ zv , ZEND_AST_PROP_GROUP , ast -> attr , zend_ast_get_lineno (ast ), state , 2 , & type_zval , & prop_group_zval );
968
+ }
884
969
ast_update_property_long (& prop_group_zval , AST_STR (str_flags ), 0 , AST_CACHE_SLOT_FLAGS );
885
970
}
886
971
#endif
972
+ #if PHP_VERSION_ID < 80000
973
+ if (ast -> kind == ZEND_AST_CLASS_CONST_DECL && state -> version >= 80 ) {
974
+ zval const_decl_zval ;
975
+ zval attributes_zval ;
976
+ ZVAL_COPY_VALUE (& const_decl_zval , zv );
977
+ ZVAL_NULL (& attributes_zval );
978
+ // For version 80, create an AST_CLASS_CONST_GROUP wrapping the created AST_CLASS_CONST_DECL
979
+ ast_create_virtual_node_ex (
980
+ zv , ZEND_AST_CLASS_CONST_GROUP , 0 , zend_ast_get_lineno (ast ), state , 2 , & const_decl_zval , & attributes_zval );
981
+ }
982
+ #endif
887
983
}
888
984
889
985
static const zend_long versions [] = {50 , 60 , 70 , 80 };
0 commit comments