@@ -2174,6 +2174,7 @@ static inline void zend_update_jump_target(uint32_t opnum_jump, uint32_t opnum_t
2174
2174
zend_op * opline = & CG (active_op_array )-> opcodes [opnum_jump ];
2175
2175
switch (opline -> opcode ) {
2176
2176
case ZEND_JMP :
2177
+ case ZEND_JMP_STATIC_DEF :
2177
2178
opline -> op1 .opline_num = opnum_target ;
2178
2179
break ;
2179
2180
case ZEND_JMPZ :
@@ -4778,16 +4779,53 @@ static void zend_compile_static_var_common(zend_string *var_name, zval *value, u
4778
4779
static void zend_compile_static_var (zend_ast * ast ) /* {{{ */
4779
4780
{
4780
4781
zend_ast * var_ast = ast -> child [0 ];
4781
- zend_ast * * value_ast_ptr = & ast -> child [1 ];
4782
- zval value_zv ;
4782
+ zend_ast * value_ast = ast -> child [1 ];
4783
+ zend_string * var_name = zend_ast_get_str ( var_ast ) ;
4783
4784
4784
- if (* value_ast_ptr ) {
4785
- zend_const_expr_to_zval (& value_zv , value_ast_ptr , /* allow_dynamic */ true);
4786
- } else {
4787
- ZVAL_NULL (& value_zv );
4785
+ if (zend_string_equals_literal (var_name , "this" )) {
4786
+ zend_error_noreturn (E_COMPILE_ERROR , "Cannot use $this as static variable" );
4788
4787
}
4789
4788
4790
- zend_compile_static_var_common (zend_ast_get_str (var_ast ), & value_zv , ZEND_BIND_REF );
4789
+ if (!value_ast ) {
4790
+ zval value_zv ;
4791
+ ZVAL_NULL (& value_zv );
4792
+ zend_compile_static_var_common (zend_ast_get_str (var_ast ), & value_zv , ZEND_BIND_REF );
4793
+ } else {
4794
+ zend_op * opline ;
4795
+
4796
+ if (!CG (active_op_array )-> static_variables ) {
4797
+ if (CG (active_op_array )-> scope ) {
4798
+ CG (active_op_array )-> scope -> ce_flags |= ZEND_HAS_STATIC_IN_METHODS ;
4799
+ }
4800
+ CG (active_op_array )-> static_variables = zend_new_array (8 );
4801
+ }
4802
+
4803
+ if (zend_hash_exists (CG (active_op_array )-> static_variables , var_name )) {
4804
+ zend_error_noreturn (E_COMPILE_ERROR , "Duplicate declaration of static variable $%s" , ZSTR_VAL (var_name ));
4805
+ }
4806
+
4807
+ zval placeholder ;
4808
+ ZVAL_UNDEF (& placeholder );
4809
+ zval * placeholder_ptr = zend_hash_update (CG (active_op_array )-> static_variables , var_name , & placeholder );
4810
+ uint32_t placeholder_offset = (uint32_t )((char * )placeholder_ptr - (char * )CG (active_op_array )-> static_variables -> arData );
4811
+
4812
+ uint32_t jmp_opnum = get_next_op_number ();
4813
+ opline = zend_emit_op (NULL , ZEND_JMP_STATIC_DEF , NULL , NULL );
4814
+ opline -> extended_value = placeholder_offset ;
4815
+
4816
+ znode expr ;
4817
+ zend_compile_expr (& expr , value_ast );
4818
+
4819
+ opline = zend_emit_op (NULL , ZEND_ASSIGN_STATIC , & expr , NULL );
4820
+ opline -> extended_value = placeholder_offset ;
4821
+
4822
+ zend_update_jump_target_to_next (jmp_opnum );
4823
+
4824
+ opline = zend_emit_op (NULL , ZEND_BIND_STATIC , NULL , NULL );
4825
+ opline -> op1_type = IS_CV ;
4826
+ opline -> op1 .var = lookup_cv (var_name );
4827
+ opline -> extended_value = placeholder_offset | ZEND_BIND_REF ;
4828
+ }
4791
4829
}
4792
4830
/* }}} */
4793
4831
0 commit comments