@@ -2055,7 +2055,8 @@ static void zend_check_live_ranges(zend_op *opline) /* {{{ */
2055
2055
opline -> opcode == ZEND_ROPE_END ||
2056
2056
opline -> opcode == ZEND_END_SILENCE ||
2057
2057
opline -> opcode == ZEND_FETCH_LIST ||
2058
- opline -> opcode == ZEND_VERIFY_RETURN_TYPE ) {
2058
+ opline -> opcode == ZEND_VERIFY_RETURN_TYPE ||
2059
+ opline -> opcode == ZEND_BIND_LEXICAL ) {
2059
2060
/* these opcodes are handled separately */
2060
2061
} else {
2061
2062
zend_find_live_range (opline , opline -> op1_type , opline -> op1 .var );
@@ -4893,28 +4894,44 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */
4893
4894
}
4894
4895
/* }}} */
4895
4896
4896
- void zend_compile_closure_uses ( zend_ast * ast ) /* {{{ */
4897
+ static void zend_compile_closure_binding ( znode * closure , zend_ast * uses_ast ) /* {{{ */
4897
4898
{
4898
- zend_ast_list * list = zend_ast_get_list (ast );
4899
+ zend_ast_list * list = zend_ast_get_list (uses_ast );
4899
4900
uint32_t i ;
4900
4901
4901
4902
for (i = 0 ; i < list -> children ; ++ i ) {
4902
- zend_ast * var_ast = list -> child [i ];
4903
- zend_string * name = zend_ast_get_str (var_ast );
4904
- zend_bool by_ref = var_ast -> attr ;
4905
- zval zv ;
4903
+ zend_ast * var_name_ast = list -> child [i ];
4904
+ zend_string * var_name = zend_ast_get_str (var_name_ast );
4905
+ zend_bool by_ref = var_name_ast -> attr ;
4906
+ zend_op * opline ;
4906
4907
4907
- if (zend_string_equals_literal (name , "this" )) {
4908
+ if (zend_string_equals_literal (var_name , "this" )) {
4908
4909
zend_error_noreturn (E_COMPILE_ERROR , "Cannot use $this as lexical variable" );
4909
4910
}
4910
4911
4911
- if (zend_is_auto_global (name )) {
4912
+ if (zend_is_auto_global (var_name )) {
4912
4913
zend_error_noreturn (E_COMPILE_ERROR , "Cannot use auto-global as lexical variable" );
4913
4914
}
4914
4915
4915
- ZVAL_NULL (& zv );
4916
- Z_CONST_FLAGS (zv ) = by_ref ? IS_LEXICAL_REF : IS_LEXICAL_VAR ;
4916
+ opline = zend_emit_op (NULL , ZEND_BIND_LEXICAL , closure , NULL );
4917
+ opline -> op2_type = IS_CV ;
4918
+ opline -> op2 .var = lookup_cv (CG (active_op_array ), zend_string_copy (var_name ));
4919
+ opline -> extended_value = by_ref ;
4920
+ }
4921
+ }
4922
+ /* }}} */
4917
4923
4924
+ void zend_compile_closure_uses (zend_ast * ast ) /* {{{ */
4925
+ {
4926
+ zend_ast_list * list = zend_ast_get_list (ast );
4927
+ uint32_t i ;
4928
+
4929
+ for (i = 0 ; i < list -> children ; ++ i ) {
4930
+ zend_ast * var_ast = list -> child [i ];
4931
+ zend_bool by_ref = var_ast -> attr ;
4932
+
4933
+ zval zv ;
4934
+ ZVAL_NULL (& zv );
4918
4935
zend_compile_static_var_common (var_ast , & zv , by_ref );
4919
4936
}
4920
4937
}
@@ -5166,6 +5183,9 @@ void zend_compile_func_decl(znode *result, zend_ast *ast) /* {{{ */
5166
5183
zend_begin_method_decl (op_array , decl -> name , has_body );
5167
5184
} else {
5168
5185
zend_begin_func_decl (result , op_array , decl );
5186
+ if (uses_ast ) {
5187
+ zend_compile_closure_binding (result , uses_ast );
5188
+ }
5169
5189
}
5170
5190
5171
5191
CG (active_op_array ) = op_array ;
0 commit comments