diff options
| -rw-r--r-- | Zend/tests/generators/errors/yield_in_normal_function_error.phpt | 2 | ||||
| -rw-r--r-- | Zend/tests/generators/errors/yield_outside_function_error.phpt | 2 | ||||
| -rw-r--r-- | Zend/zend_compile.c | 23 | ||||
| -rw-r--r-- | Zend/zend_compile.h | 1 | ||||
| -rw-r--r-- | Zend/zend_generators.c | 3 | ||||
| -rw-r--r-- | Zend/zend_language_parser.y | 1 | ||||
| -rw-r--r-- | Zend/zend_language_scanner.c | 2 | ||||
| -rw-r--r-- | Zend/zend_language_scanner_defs.h | 2 | ||||
| -rw-r--r-- | Zend/zend_vm_def.h | 5 | ||||
| -rw-r--r-- | Zend/zend_vm_execute.h | 45 | ||||
| -rw-r--r-- | Zend/zend_vm_opcodes.h | 1 |
11 files changed, 80 insertions, 7 deletions
diff --git a/Zend/tests/generators/errors/yield_in_normal_function_error.phpt b/Zend/tests/generators/errors/yield_in_normal_function_error.phpt index 802510d29c..4670a41542 100644 --- a/Zend/tests/generators/errors/yield_in_normal_function_error.phpt +++ b/Zend/tests/generators/errors/yield_in_normal_function_error.phpt @@ -9,4 +9,4 @@ function foo() { ?> --EXPECTF-- -Fatal error: The "yield" statement can only be used inside a generator function in %s on line %d +Fatal error: The "yield" expression can only be used inside a generator function in %s on line %d diff --git a/Zend/tests/generators/errors/yield_outside_function_error.phpt b/Zend/tests/generators/errors/yield_outside_function_error.phpt index fd7169d5f2..5f47e75366 100644 --- a/Zend/tests/generators/errors/yield_outside_function_error.phpt +++ b/Zend/tests/generators/errors/yield_outside_function_error.phpt @@ -7,4 +7,4 @@ yield "Test"; ?> --EXPECTF-- -Fatal error: The "yield" statement can only be used inside a generator function in %s on line %d +Fatal error: The "yield" expression can only be used inside a generator function in %s on line %d diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index da61b76662..35ff2bbf52 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2667,7 +2667,7 @@ void zend_do_yield(znode *result, const znode *value, const znode *key TSRMLS_DC zend_op *opline; if ((CG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) == 0) { - zend_error(E_COMPILE_ERROR, "The \"yield\" statement can only be used inside a generator function"); + zend_error(E_COMPILE_ERROR, "The \"yield\" expression can only be used inside a generator function"); } opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -2692,6 +2692,27 @@ void zend_do_yield(znode *result, const znode *value, const znode *key TSRMLS_DC } /* }}} */ +void zend_do_delegate_yield(znode *result, const znode *value TSRMLS_DC) /* {{{ */ +{ + zend_op *opline; + + if ((CG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) == 0) { + zend_error(E_COMPILE_ERROR, "The \"yield*\" expression can only be used inside a generator function"); + } + + opline = get_next_op(CG(active_op_array) TSRMLS_CC); + + opline->opcode = ZEND_DELEGATE_YIELD; + + SET_NODE(opline->op1, value); + SET_UNUSED(opline->op2); + + opline->result_type = IS_VAR; + opline->result.var = get_temporary_variable(CG(active_op_array)); + GET_NODE(result, opline->result); +} +/* }}} */ + void zend_do_suspend_if_generator(TSRMLS_D) /* {{{ */ { zend_op *opline; diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index ec86ed86de..d0587d1faa 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 *result, const znode *value, const znode *key TSRMLS_DC); +void zend_do_delegate_yield(znode *result, const znode *value TSRMLS_DC); void zend_do_suspend_if_generator(TSRMLS_D); void zend_do_handle_exception(TSRMLS_D); diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index 6efa710660..f8374b8a65 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -245,7 +245,7 @@ static void zend_generator_clone_storage(zend_generator *orig, zend_generator ** } /* Update the send_target to use the temporary variable with the same - * offset as the original generator, but in out temporary variable + * offset as the original generator, but in our temporary variable * memory segment. */ if (orig->send_target) { size_t offset = (char *) orig->send_target - (char *) execute_data->Ts; @@ -536,7 +536,6 @@ ZEND_METHOD(Generator, send) /* The sent value was initialized to NULL, so dtor that */ zval_ptr_dtor(&generator->send_target->var.ptr); - /* Set new sent value */ Z_ADDREF_P(value); generator->send_target->var.ptr = value; diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 16c0ea2b2c..02aa694c6e 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -804,6 +804,7 @@ expr_without_variable: | T_PRINT expr { zend_do_print(&$$, &$2 TSRMLS_CC); } | T_YIELD { zend_do_yield(&$$, NULL, NULL TSRMLS_CC); } | T_YIELD expr { zend_do_yield(&$$, &$2, NULL TSRMLS_CC); } + | T_YIELD '*' expr { zend_do_delegate_yield(&$$, &$3 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 { zend_do_suspend_if_generator(TSRMLS_C); } '{' inner_statement_list '}' { zend_do_end_function_declaration(&$1 TSRMLS_CC); $$ = $4; } diff --git a/Zend/zend_language_scanner.c b/Zend/zend_language_scanner.c index a388e96a26..e20fc19581 100644 --- a/Zend/zend_language_scanner.c +++ b/Zend/zend_language_scanner.c @@ -1,4 +1,4 @@ -/* Generated by re2c 0.13.5 on Tue May 15 13:07:23 2012 */ +/* Generated by re2c 0.13.5 on Sat Jun 16 12:57:03 2012 */ #line 1 "Zend/zend_language_scanner.l" /* +----------------------------------------------------------------------+ diff --git a/Zend/zend_language_scanner_defs.h b/Zend/zend_language_scanner_defs.h index 981c342e19..869d54349d 100644 --- a/Zend/zend_language_scanner_defs.h +++ b/Zend/zend_language_scanner_defs.h @@ -1,4 +1,4 @@ -/* Generated by re2c 0.13.5 on Tue May 15 13:07:23 2012 */ +/* Generated by re2c 0.13.5 on Sat Jun 16 12:57:03 2012 */ #line 3 "Zend/zend_language_scanner_defs.h" enum YYCONDTYPE { diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 27afc49fa3..e5d8a7624a 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -5406,4 +5406,9 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE ZEND_VM_RETURN(); } +ZEND_VM_HANDLER(161, ZEND_DELEGATE_YIELD, CONST|TMP|VAR|CV, ANY) +{ + ZEND_VM_NEXT_OPCODE(); +} + ZEND_VM_EXPORT_HELPER(zend_do_fcall, zend_do_fcall_common_helper) diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 987e4ceee0..6f1a885bb6 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -3079,6 +3079,11 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_VAR_SPEC_CONST_HANDLER(ZEND_OPCODE_HAND ZEND_VM_NEXT_OPCODE(); } +static int ZEND_FASTCALL ZEND_DELEGATE_YIELD_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_FASTCALL ZEND_ADD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -8182,6 +8187,11 @@ static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_A ZEND_VM_NEXT_OPCODE(); } +static int ZEND_FASTCALL ZEND_DELEGATE_YIELD_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_FASTCALL ZEND_ADD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -13362,6 +13372,11 @@ static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_A ZEND_VM_NEXT_OPCODE(); } +static int ZEND_FASTCALL ZEND_DELEGATE_YIELD_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -30224,6 +30239,11 @@ static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_AR ZEND_VM_NEXT_OPCODE(); } +static int ZEND_FASTCALL ZEND_DELEGATE_YIELD_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_FASTCALL ZEND_ADD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -43545,6 +43565,31 @@ void zend_init_opcodes_handlers(void) ZEND_YIELD_SPEC_CV_VAR_HANDLER, ZEND_YIELD_SPEC_CV_UNUSED_HANDLER, ZEND_YIELD_SPEC_CV_CV_HANDLER, + ZEND_DELEGATE_YIELD_SPEC_CONST_HANDLER, + ZEND_DELEGATE_YIELD_SPEC_CONST_HANDLER, + ZEND_DELEGATE_YIELD_SPEC_CONST_HANDLER, + ZEND_DELEGATE_YIELD_SPEC_CONST_HANDLER, + ZEND_DELEGATE_YIELD_SPEC_CONST_HANDLER, + ZEND_DELEGATE_YIELD_SPEC_TMP_HANDLER, + ZEND_DELEGATE_YIELD_SPEC_TMP_HANDLER, + ZEND_DELEGATE_YIELD_SPEC_TMP_HANDLER, + ZEND_DELEGATE_YIELD_SPEC_TMP_HANDLER, + ZEND_DELEGATE_YIELD_SPEC_TMP_HANDLER, + ZEND_DELEGATE_YIELD_SPEC_VAR_HANDLER, + ZEND_DELEGATE_YIELD_SPEC_VAR_HANDLER, + ZEND_DELEGATE_YIELD_SPEC_VAR_HANDLER, + ZEND_DELEGATE_YIELD_SPEC_VAR_HANDLER, + ZEND_DELEGATE_YIELD_SPEC_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_DELEGATE_YIELD_SPEC_CV_HANDLER, + ZEND_DELEGATE_YIELD_SPEC_CV_HANDLER, + ZEND_DELEGATE_YIELD_SPEC_CV_HANDLER, + ZEND_DELEGATE_YIELD_SPEC_CV_HANDLER, + ZEND_DELEGATE_YIELD_SPEC_CV_HANDLER, ZEND_NULL_HANDLER }; zend_opcode_handlers = (opcode_handler_t*)labels; diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h index 53e00a1743..46a711d179 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -161,3 +161,4 @@ #define ZEND_JMP_SET_VAR 158 #define ZEND_SUSPEND_AND_RETURN_GENERATOR 159 #define ZEND_YIELD 160 +#define ZEND_DELEGATE_YIELD 161 |
