@@ -4247,7 +4247,7 @@ void zend_compile_global_var(zend_ast *ast) /* {{{ */
4247
4247
}
4248
4248
/* }}} */
4249
4249
4250
- static void zend_compile_static_var_common (zend_ast * var_ast , zval * value , zend_bool by_ref ) /* {{{ */
4250
+ static void zend_compile_static_var_common (zend_ast * var_ast , zval * value , uint32_t by_ref ) /* {{{ */
4251
4251
{
4252
4252
znode var_node ;
4253
4253
zend_op * opline ;
@@ -4274,7 +4274,7 @@ static void zend_compile_static_var_common(zend_ast *var_ast, zval *value, zend_
4274
4274
}
4275
4275
CG (active_op_array )-> static_variables = zend_array_dup (CG (active_op_array )-> static_variables );
4276
4276
}
4277
- zend_hash_update (CG (active_op_array )-> static_variables , var_name , value );
4277
+ value = zend_hash_update (CG (active_op_array )-> static_variables , var_name , value );
4278
4278
4279
4279
if (zend_string_equals_literal (var_name , "this" )) {
4280
4280
zend_error_noreturn (E_COMPILE_ERROR , "Cannot use $this as static variable" );
@@ -4283,7 +4283,7 @@ static void zend_compile_static_var_common(zend_ast *var_ast, zval *value, zend_
4283
4283
opline = zend_emit_op (NULL , ZEND_BIND_STATIC , NULL , & var_node );
4284
4284
opline -> op1_type = IS_CV ;
4285
4285
opline -> op1 .var = lookup_cv (CG (active_op_array ), var_name );
4286
- opline -> extended_value = by_ref ;
4286
+ opline -> extended_value = ( uint32_t )(( char * ) value - ( char * ) CG ( active_op_array ) -> static_variables -> arData ) | by_ref ;
4287
4287
}
4288
4288
/* }}} */
4289
4289
@@ -4299,7 +4299,7 @@ void zend_compile_static_var(zend_ast *ast) /* {{{ */
4299
4299
ZVAL_NULL (& value_zv );
4300
4300
}
4301
4301
4302
- zend_compile_static_var_common (var_ast , & value_zv , 1 );
4302
+ zend_compile_static_var_common (var_ast , & value_zv , ZEND_BIND_REF );
4303
4303
}
4304
4304
/* }}} */
4305
4305
@@ -5672,16 +5672,32 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */
5672
5672
}
5673
5673
/* }}} */
5674
5674
5675
- static void zend_compile_closure_binding (znode * closure , zend_ast * uses_ast ) /* {{{ */
5675
+ static void zend_compile_closure_binding (znode * closure , zend_op_array * op_array , zend_ast * uses_ast ) /* {{{ */
5676
5676
{
5677
5677
zend_ast_list * list = zend_ast_get_list (uses_ast );
5678
5678
uint32_t i ;
5679
5679
5680
+ if (!list -> children ) {
5681
+ return ;
5682
+ }
5683
+
5684
+ if (!op_array -> static_variables ) {
5685
+ op_array -> static_variables = zend_new_array (8 );
5686
+ }
5687
+
5688
+ if (GC_REFCOUNT (op_array -> static_variables ) > 1 ) {
5689
+ if (!(GC_FLAGS (op_array -> static_variables ) & IS_ARRAY_IMMUTABLE )) {
5690
+ GC_DELREF (op_array -> static_variables );
5691
+ }
5692
+ op_array -> static_variables = zend_array_dup (op_array -> static_variables );
5693
+ }
5694
+
5680
5695
for (i = 0 ; i < list -> children ; ++ i ) {
5681
5696
zend_ast * var_name_ast = list -> child [i ];
5682
5697
zend_string * var_name = zval_make_interned_string (zend_ast_get_zval (var_name_ast ));
5683
- zend_bool by_ref = var_name_ast -> attr ;
5698
+ uint32_t by_ref = var_name_ast -> attr ;
5684
5699
zend_op * opline ;
5700
+ zval * value ;
5685
5701
5686
5702
if (zend_string_equals_literal (var_name , "this" )) {
5687
5703
zend_error_noreturn (E_COMPILE_ERROR , "Cannot use $this as lexical variable" );
@@ -5691,10 +5707,16 @@ static void zend_compile_closure_binding(znode *closure, zend_ast *uses_ast) /*
5691
5707
zend_error_noreturn (E_COMPILE_ERROR , "Cannot use auto-global as lexical variable" );
5692
5708
}
5693
5709
5710
+ value = zend_hash_add (op_array -> static_variables , var_name , & EG (uninitialized_zval ));
5711
+ if (!value ) {
5712
+ zend_error_noreturn (E_COMPILE_ERROR ,
5713
+ "Cannot use variable $%s twice" , ZSTR_VAL (var_name ));
5714
+ }
5715
+
5694
5716
opline = zend_emit_op (NULL , ZEND_BIND_LEXICAL , closure , NULL );
5695
5717
opline -> op2_type = IS_CV ;
5696
5718
opline -> op2 .var = lookup_cv (CG (active_op_array ), var_name );
5697
- opline -> extended_value = by_ref ;
5719
+ opline -> extended_value = ( uint32_t )(( char * ) value - ( char * ) op_array -> static_variables -> arData ) | by_ref ;
5698
5720
}
5699
5721
}
5700
5722
/* }}} */
@@ -5708,16 +5730,10 @@ void zend_compile_closure_uses(zend_ast *ast) /* {{{ */
5708
5730
for (i = 0 ; i < list -> children ; ++ i ) {
5709
5731
zend_ast * var_ast = list -> child [i ];
5710
5732
zend_string * var_name = zend_ast_get_str (var_ast );
5711
- zend_bool by_ref = var_ast -> attr ;
5733
+ uint32_t by_ref = var_ast -> attr ;
5712
5734
zval zv ;
5713
5735
ZVAL_NULL (& zv );
5714
5736
5715
- if (op_array -> static_variables
5716
- && zend_hash_exists (op_array -> static_variables , var_name )) {
5717
- zend_error_noreturn (E_COMPILE_ERROR ,
5718
- "Cannot use variable $%s twice" , ZSTR_VAL (var_name ));
5719
- }
5720
-
5721
5737
{
5722
5738
int i ;
5723
5739
for (i = 0 ; i < op_array -> last_var ; i ++ ) {
@@ -5996,7 +6012,7 @@ void zend_compile_func_decl(znode *result, zend_ast *ast) /* {{{ */
5996
6012
} else {
5997
6013
zend_begin_func_decl (result , op_array , decl );
5998
6014
if (uses_ast ) {
5999
- zend_compile_closure_binding (result , uses_ast );
6015
+ zend_compile_closure_binding (result , op_array , uses_ast );
6000
6016
}
6001
6017
}
6002
6018
0 commit comments