summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikic@php.net>2012-05-19 20:19:45 +0200
committerNikita Popov <nikic@php.net>2012-05-19 20:19:45 +0200
commite14cfafcbfbe58e0fc3f7b814698a908b0dffca5 (patch)
treedf480de9c03dcd3489a6563b7e68bacfb26d3101
parentfd2a109f86d18b93d29153c2ddfa605651c7df05 (diff)
downloadphp-git-e14cfafcbfbe58e0fc3f7b814698a908b0dffca5.tar.gz
Add zend_do_suspend_if_generator calls
The execution of generator functions will be suspended right after the arguments were RECVed. This will be done in zend_do_suspend_if_generator.
-rw-r--r--Zend/zend_compile.c11
-rw-r--r--Zend/zend_compile.h1
-rw-r--r--Zend/zend_language_parser.y12
3 files changed, 20 insertions, 4 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index d2b3536788..831f9f9d3f 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -2668,6 +2668,17 @@ void zend_do_yield(znode *expr TSRMLS_DC) /* {{{ */
}
/* }}} */
+void zend_do_suspend_if_generator(TSRMLS_D) /* {{{ */
+{
+ // we only suspend execution if the current function is a generator
+ if ((CG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) == 0) {
+ return;
+ }
+
+ /* do nothing for now */
+}
+/* }}} */
+
static int zend_add_try_element(zend_uint try_op TSRMLS_DC) /* {{{ */
{
int try_catch_offset = CG(active_op_array)->last_try_catch++;
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index 375f953d86..5365f9693d 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -491,6 +491,7 @@ int zend_do_begin_class_member_function_call(znode *class_name, znode *method_na
void zend_do_end_function_call(znode *function_name, znode *result, const znode *argument_list, int is_method, int is_dynamic_fcall TSRMLS_DC);
void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC);
void zend_do_yield(znode *expr TSRMLS_DC);
+void zend_do_suspend_if_generator(TSRMLS_D);
void zend_do_handle_exception(TSRMLS_D);
void zend_do_begin_lambda_function_declaration(znode *result, znode *function_token, int is_generator, int return_reference, int is_static TSRMLS_DC);
diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y
index 2fcf6740c4..2045a5e465 100644
--- a/Zend/zend_language_parser.y
+++ b/Zend/zend_language_parser.y
@@ -372,7 +372,8 @@ is_reference:
unticked_function_declaration_statement:
function is_generator is_reference T_STRING { zend_do_begin_function_declaration(&$1, &$4, 0, $2.op_type, $3.op_type, NULL TSRMLS_CC); }
- '(' parameter_list ')' '{' inner_statement_list '}' { zend_do_end_function_declaration(&$1 TSRMLS_CC); }
+ '(' parameter_list ')' { zend_do_suspend_if_generator(TSRMLS_C); }
+ '{' inner_statement_list '}' { zend_do_end_function_declaration(&$1 TSRMLS_CC); }
;
unticked_class_declaration_statement:
@@ -583,7 +584,8 @@ class_statement:
| class_constant_declaration ';'
| trait_use_statement
| method_modifiers function is_generator is_reference T_STRING { zend_do_begin_function_declaration(&$2, &$5, 1, $3.op_type, $4.op_type, &$1 TSRMLS_CC); }
- '(' parameter_list ')' method_body { zend_do_abstract_method(&$5, &$1, &$10 TSRMLS_CC); zend_do_end_function_declaration(&$2 TSRMLS_CC); }
+ '(' parameter_list ')' { zend_do_suspend_if_generator(TSRMLS_C); }
+ method_body { zend_do_abstract_method(&$5, &$1, &$11 TSRMLS_CC); zend_do_end_function_declaration(&$2 TSRMLS_CC); }
;
trait_use_statement:
@@ -800,9 +802,11 @@ expr_without_variable:
| '`' backticks_expr '`' { zend_do_shell_exec(&$$, &$2 TSRMLS_CC); }
| T_PRINT expr { zend_do_print(&$$, &$2 TSRMLS_CC); }
| function is_generator is_reference { zend_do_begin_lambda_function_declaration(&$$, &$1, $2.op_type, $3.op_type, 0 TSRMLS_CC); }
- '(' parameter_list ')' lexical_vars '{' inner_statement_list '}' { zend_do_end_function_declaration(&$1 TSRMLS_CC); $$ = $4; }
+ '(' parameter_list ')' lexical_vars { zend_do_suspend_if_generator(TSRMLS_C); }
+ '{' inner_statement_list '}' { zend_do_end_function_declaration(&$1 TSRMLS_CC); $$ = $4; }
| T_STATIC function is_generator is_reference { zend_do_begin_lambda_function_declaration(&$$, &$2, $3.op_type, $4.op_type, 1 TSRMLS_CC); }
- '(' parameter_list ')' lexical_vars '{' inner_statement_list '}' { zend_do_end_function_declaration(&$2 TSRMLS_CC); $$ = $5; }
+ '(' parameter_list ')' lexical_vars { zend_do_suspend_if_generator(TSRMLS_C); }
+ '{' inner_statement_list '}' { zend_do_end_function_declaration(&$2 TSRMLS_CC); $$ = $5; }
;
combined_scalar_offset: