@@ -2169,6 +2169,7 @@ static inline void zend_update_jump_target(uint32_t opnum_jump, uint32_t opnum_t
2169
2169
zend_op * opline = & CG (active_op_array )-> opcodes [opnum_jump ];
2170
2170
switch (opline -> opcode ) {
2171
2171
case ZEND_JMP :
2172
+ case ZEND_JMP_STATIC_DEF :
2172
2173
opline -> op1 .opline_num = opnum_target ;
2173
2174
break ;
2174
2175
case ZEND_JMPZ :
@@ -4754,16 +4755,53 @@ static void zend_compile_static_var_common(zend_string *var_name, zval *value, u
4754
4755
static void zend_compile_static_var (zend_ast * ast ) /* {{{ */
4755
4756
{
4756
4757
zend_ast * var_ast = ast -> child [0 ];
4757
- zend_ast * * value_ast_ptr = & ast -> child [1 ];
4758
- zval value_zv ;
4758
+ zend_ast * value_ast = ast -> child [1 ];
4759
+ zend_string * var_name = zend_ast_get_str ( var_ast ) ;
4759
4760
4760
- if (* value_ast_ptr ) {
4761
- zend_const_expr_to_zval (& value_zv , value_ast_ptr , /* allow_dynamic */ true);
4762
- } else {
4763
- ZVAL_NULL (& value_zv );
4761
+ if (zend_string_equals_literal (var_name , "this" )) {
4762
+ zend_error_noreturn (E_COMPILE_ERROR , "Cannot use $this as static variable" );
4764
4763
}
4765
4764
4766
- zend_compile_static_var_common (zend_ast_get_str (var_ast ), & value_zv , ZEND_BIND_REF );
4765
+ if (!value_ast ) {
4766
+ zval value_zv ;
4767
+ ZVAL_NULL (& value_zv );
4768
+ zend_compile_static_var_common (zend_ast_get_str (var_ast ), & value_zv , ZEND_BIND_REF );
4769
+ } else {
4770
+ zend_op * opline ;
4771
+
4772
+ if (!CG (active_op_array )-> static_variables ) {
4773
+ if (CG (active_op_array )-> scope ) {
4774
+ CG (active_op_array )-> scope -> ce_flags |= ZEND_HAS_STATIC_IN_METHODS ;
4775
+ }
4776
+ CG (active_op_array )-> static_variables = zend_new_array (8 );
4777
+ }
4778
+
4779
+ if (zend_hash_exists (CG (active_op_array )-> static_variables , var_name )) {
4780
+ zend_error_noreturn (E_COMPILE_ERROR , "Duplicate declaration of static variable $%s" , ZSTR_VAL (var_name ));
4781
+ }
4782
+
4783
+ zval placeholder ;
4784
+ ZVAL_UNDEF (& placeholder );
4785
+ zval * placeholder_ptr = zend_hash_update (CG (active_op_array )-> static_variables , var_name , & placeholder );
4786
+ uint32_t placeholder_offset = (uint32_t )((char * )placeholder_ptr - (char * )CG (active_op_array )-> static_variables -> arData );
4787
+
4788
+ uint32_t jmp_opnum = get_next_op_number ();
4789
+ opline = zend_emit_op (NULL , ZEND_JMP_STATIC_DEF , NULL , NULL );
4790
+ opline -> extended_value = placeholder_offset ;
4791
+
4792
+ znode expr ;
4793
+ zend_compile_expr (& expr , value_ast );
4794
+
4795
+ opline = zend_emit_op (NULL , ZEND_ASSIGN_STATIC , & expr , NULL );
4796
+ opline -> extended_value = placeholder_offset ;
4797
+
4798
+ zend_update_jump_target_to_next (jmp_opnum );
4799
+
4800
+ opline = zend_emit_op (NULL , ZEND_BIND_STATIC , NULL , NULL );
4801
+ opline -> op1_type = IS_CV ;
4802
+ opline -> op1 .var = lookup_cv (var_name );
4803
+ opline -> extended_value = placeholder_offset | ZEND_BIND_REF ;
4804
+ }
4767
4805
}
4768
4806
/* }}} */
4769
4807
0 commit comments