@@ -121,7 +121,6 @@ ZEND_METHOD(Closure, call)
121121 zend_closure * closure ;
122122 zend_fcall_info fci ;
123123 zend_fcall_info_cache fci_cache ;
124- zend_function my_function ;
125124 zend_object * newobj ;
126125 zend_class_entry * newclass ;
127126
@@ -142,55 +141,71 @@ ZEND_METHOD(Closure, call)
142141 return ;
143142 }
144143
144+ fci_cache .called_scope = newclass ;
145+ fci_cache .object = fci .object = newobj ;
146+
147+ fci .size = sizeof (fci );
148+ ZVAL_OBJ (& fci .function_name , & closure -> std );
149+ ZVAL_UNDEF (& closure_result );
150+ fci .retval = & closure_result ;
151+
145152 if (closure -> func .common .fn_flags & ZEND_ACC_GENERATOR ) {
146153 zval new_closure ;
147154 zend_create_closure (& new_closure , & closure -> func , newclass , closure -> called_scope , newthis );
148155 closure = (zend_closure * ) Z_OBJ (new_closure );
149156 fci_cache .function_handler = & closure -> func ;
157+
158+ zend_call_function (& fci , & fci_cache );
159+
160+ /* copied upon generator creation */
161+ GC_DELREF (& closure -> std );
150162 } else {
151- memcpy (& my_function , & closure -> func , closure -> func .type == ZEND_USER_FUNCTION ? sizeof (zend_op_array ) : sizeof (zend_internal_function ));
152- my_function .common .fn_flags &= ~ZEND_ACC_CLOSURE ;
163+ zend_function * my_function ;
164+ if (ZEND_USER_CODE (closure -> func .type )) {
165+ my_function = emalloc (sizeof (zend_op_array ));
166+ memcpy (my_function , & closure -> func , sizeof (zend_op_array ));
167+ } else {
168+ my_function = emalloc (sizeof (zend_internal_function ));
169+ memcpy (my_function , & closure -> func , sizeof (zend_internal_function ));
170+ }
171+ my_function -> common .fn_flags &= ~ZEND_ACC_CLOSURE ;
153172 /* use scope of passed object */
154- my_function . common .scope = newclass ;
173+ my_function -> common .scope = newclass ;
155174 if (closure -> func .type == ZEND_INTERNAL_FUNCTION ) {
156- my_function . internal_function .handler = closure -> orig_internal_handler ;
175+ my_function -> internal_function .handler = closure -> orig_internal_handler ;
157176 }
158- fci_cache .function_handler = & my_function ;
177+ fci_cache .function_handler = my_function ;
159178
160179 /* Runtime cache relies on bound scope to be immutable, hence we need a separate rt cache in case scope changed */
161- if (ZEND_USER_CODE (my_function . type )
180+ if (ZEND_USER_CODE (my_function -> type )
162181 && (closure -> func .common .scope != newclass
163182 || (closure -> func .common .fn_flags & ZEND_ACC_HEAP_RT_CACHE ))) {
164183 void * ptr ;
165184
166- my_function . op_array .fn_flags |= ZEND_ACC_HEAP_RT_CACHE ;
167- ptr = emalloc (my_function . op_array .cache_size );
168- ZEND_MAP_PTR_INIT (my_function . op_array .run_time_cache , ptr );
169- memset (ptr , 0 , my_function . op_array .cache_size );
185+ my_function -> op_array .fn_flags |= ZEND_ACC_HEAP_RT_CACHE ;
186+ ptr = emalloc (my_function -> op_array .cache_size );
187+ ZEND_MAP_PTR_INIT (my_function -> op_array .run_time_cache , ptr );
188+ memset (ptr , 0 , my_function -> op_array .cache_size );
170189 }
171- }
172190
173- fci_cache .called_scope = newclass ;
174- fci_cache .object = fci .object = newobj ;
191+ zend_call_function (& fci , & fci_cache );
175192
176- fci .size = sizeof (fci );
177- ZVAL_OBJ (& fci .function_name , & closure -> std );
178- fci .retval = & closure_result ;
193+ if (ZEND_USER_CODE (my_function -> type )) {
194+ if (fci_cache .function_handler -> common .fn_flags & ZEND_ACC_HEAP_RT_CACHE ) {
195+ efree (ZEND_MAP_PTR (my_function -> op_array .run_time_cache ));
196+ }
197+ efree_size (my_function , sizeof (zend_op_array ));
198+ } else {
199+ efree_size (my_function , sizeof (zend_internal_function ));
200+ }
201+ }
179202
180- if (zend_call_function ( & fci , & fci_cache ) == SUCCESS && Z_TYPE (closure_result ) != IS_UNDEF ) {
203+ if (Z_TYPE (closure_result ) != IS_UNDEF ) {
181204 if (Z_ISREF (closure_result )) {
182205 zend_unwrap_reference (& closure_result );
183206 }
184207 ZVAL_COPY_VALUE (return_value , & closure_result );
185208 }
186-
187- if (fci_cache .function_handler -> common .fn_flags & ZEND_ACC_GENERATOR ) {
188- /* copied upon generator creation */
189- GC_DELREF (& closure -> std );
190- } else if (ZEND_USER_CODE (my_function .type )
191- && (fci_cache .function_handler -> common .fn_flags & ZEND_ACC_HEAP_RT_CACHE )) {
192- efree (ZEND_MAP_PTR (my_function .op_array .run_time_cache ));
193- }
194209}
195210/* }}} */
196211
0 commit comments