Skip to content

Commit

Permalink
Add sceleton for yield* expression
Browse files Browse the repository at this point in the history
This does not yet actually implement any delegation.
  • Loading branch information
nikic committed Jun 18, 2012
1 parent f169b26 commit d939d2d
Show file tree
Hide file tree
Showing 11 changed files with 80 additions and 7 deletions.
Expand Up @@ -9,4 +9,4 @@ function foo() {


?> ?>
--EXPECTF-- --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
Expand Up @@ -7,4 +7,4 @@ yield "Test";


?> ?>
--EXPECTF-- --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
23 changes: 22 additions & 1 deletion Zend/zend_compile.c
Expand Up @@ -2667,7 +2667,7 @@ void zend_do_yield(znode *result, const znode *value, const znode *key TSRMLS_DC
zend_op *opline; zend_op *opline;


if ((CG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) == 0) { 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); opline = get_next_op(CG(active_op_array) TSRMLS_CC);
Expand All @@ -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) /* {{{ */ void zend_do_suspend_if_generator(TSRMLS_D) /* {{{ */
{ {
zend_op *opline; zend_op *opline;
Expand Down
1 change: 1 addition & 0 deletions Zend/zend_compile.h
Expand Up @@ -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_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_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_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_suspend_if_generator(TSRMLS_D);
void zend_do_handle_exception(TSRMLS_D); void zend_do_handle_exception(TSRMLS_D);


Expand Down
3 changes: 1 addition & 2 deletions Zend/zend_generators.c
Expand Up @@ -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 /* 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. */ * memory segment. */
if (orig->send_target) { if (orig->send_target) {
size_t offset = (char *) orig->send_target - (char *) execute_data->Ts; size_t offset = (char *) orig->send_target - (char *) execute_data->Ts;
Expand Down Expand Up @@ -536,7 +536,6 @@ ZEND_METHOD(Generator, send)
/* The sent value was initialized to NULL, so dtor that */ /* The sent value was initialized to NULL, so dtor that */
zval_ptr_dtor(&generator->send_target->var.ptr); zval_ptr_dtor(&generator->send_target->var.ptr);



/* Set new sent value */ /* Set new sent value */
Z_ADDREF_P(value); Z_ADDREF_P(value);
generator->send_target->var.ptr = value; generator->send_target->var.ptr = value;
Expand Down
1 change: 1 addition & 0 deletions Zend/zend_language_parser.y
Expand Up @@ -804,6 +804,7 @@ expr_without_variable:
| T_PRINT expr { zend_do_print(&$$, &$2 TSRMLS_CC); } | T_PRINT expr { zend_do_print(&$$, &$2 TSRMLS_CC); }
| T_YIELD { zend_do_yield(&$$, NULL, NULL 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_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); } | 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); } '(' parameter_list ')' lexical_vars { zend_do_suspend_if_generator(TSRMLS_C); }
'{' inner_statement_list '}' { zend_do_end_function_declaration(&$1 TSRMLS_CC); $$ = $4; } '{' inner_statement_list '}' { zend_do_end_function_declaration(&$1 TSRMLS_CC); $$ = $4; }
Expand Down
2 changes: 1 addition & 1 deletion 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" #line 1 "Zend/zend_language_scanner.l"
/* /*
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
Expand Down
2 changes: 1 addition & 1 deletion 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" #line 3 "Zend/zend_language_scanner_defs.h"


enum YYCONDTYPE { enum YYCONDTYPE {
Expand Down
5 changes: 5 additions & 0 deletions Zend/zend_vm_def.h
Expand Up @@ -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_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) ZEND_VM_EXPORT_HELPER(zend_do_fcall, zend_do_fcall_common_helper)
45 changes: 45 additions & 0 deletions Zend/zend_vm_execute.h
Expand Up @@ -3079,6 +3079,11 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_VAR_SPEC_CONST_HANDLER(ZEND_OPCODE_HAND
ZEND_VM_NEXT_OPCODE(); 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) static int ZEND_FASTCALL ZEND_ADD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{ {
USE_OPLINE USE_OPLINE
Expand Down Expand Up @@ -8182,6 +8187,11 @@ static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_A
ZEND_VM_NEXT_OPCODE(); 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) static int ZEND_FASTCALL ZEND_ADD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{ {
USE_OPLINE USE_OPLINE
Expand Down Expand Up @@ -13362,6 +13372,11 @@ static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_A
ZEND_VM_NEXT_OPCODE(); 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) static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{ {
USE_OPLINE USE_OPLINE
Expand Down Expand Up @@ -30224,6 +30239,11 @@ static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_AR
ZEND_VM_NEXT_OPCODE(); 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) static int ZEND_FASTCALL ZEND_ADD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{ {
USE_OPLINE USE_OPLINE
Expand Down Expand Up @@ -43545,6 +43565,31 @@ void zend_init_opcodes_handlers(void)
ZEND_YIELD_SPEC_CV_VAR_HANDLER, ZEND_YIELD_SPEC_CV_VAR_HANDLER,
ZEND_YIELD_SPEC_CV_UNUSED_HANDLER, ZEND_YIELD_SPEC_CV_UNUSED_HANDLER,
ZEND_YIELD_SPEC_CV_CV_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_NULL_HANDLER
}; };
zend_opcode_handlers = (opcode_handler_t*)labels; zend_opcode_handlers = (opcode_handler_t*)labels;
Expand Down
1 change: 1 addition & 0 deletions Zend/zend_vm_opcodes.h
Expand Up @@ -161,3 +161,4 @@
#define ZEND_JMP_SET_VAR 158 #define ZEND_JMP_SET_VAR 158
#define ZEND_SUSPEND_AND_RETURN_GENERATOR 159 #define ZEND_SUSPEND_AND_RETURN_GENERATOR 159
#define ZEND_YIELD 160 #define ZEND_YIELD 160
#define ZEND_DELEGATE_YIELD 161

0 comments on commit d939d2d

Please sign in to comment.