Skip to content

Add generators support #177

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 74 commits into from
Sep 1, 2012
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
9b101ac
Add T_YIELD "yield" keyword
nikic May 15, 2012
252f623
Add flag for generator functions
nikic May 19, 2012
9b51a3b
Minor code cleanup
nikic May 19, 2012
fd2a109
Add error if yield is used outside a generator
nikic May 19, 2012
e14cfaf
Add zend_do_suspend_if_generator calls
nikic May 19, 2012
1cec3f1
Add ZEND_SUSPEND_AND_RETURN_GENERATOR opcode
nikic May 19, 2012
ca59e54
Add empty Generator class
nikic May 19, 2012
40b7533
Add some boilerplate code for Generator class
nikic May 20, 2012
46fa26a
Make generator functions return a Generator object
nikic May 20, 2012
5e763d9
Allocate execute_data using malloc for generators
nikic May 22, 2012
9ce9a7e
Add initial code for suspending execution
nikic May 23, 2012
2c5ecb4
Add dummy Iterator implementation
nikic May 23, 2012
ececcbc
Allow calling zend_vm_gen from everywhere
nikic May 23, 2012
f627be5
Add support for executing a zend_execute_data
nikic May 26, 2012
1a99d1c
Add way to pass generator object to opcode handlers
nikic May 26, 2012
fafce58
Add YIELD opcode implementation
nikic May 26, 2012
5bb3a99
Implement return for generators
nikic May 26, 2012
d49d397
Close generator on return
nikic May 26, 2012
cbfa96c
Remove wrong dtor call
nikic May 26, 2012
39d3d5e
Add first real generator test
nikic May 26, 2012
247bb73
Add support for generator methods
nikic May 27, 2012
64a643a
Free loop variables
nikic May 27, 2012
9f52c5c
Fix generator creation when execute_data is not nested
nikic May 27, 2012
bcc7d97
Set EG(current_execute_data)
nikic May 27, 2012
4aab08b
Properly free resources when generator return value not used
nikic May 28, 2012
b770b22
Make the GOTO and SWITCH VMs work again
nikic May 29, 2012
3600914
Add support for $generator->send()
nikic May 29, 2012
ad525c2
Allow to use yield without value
nikic May 29, 2012
12e9283
Fix segfault when send()ing to a closed generator
nikic May 29, 2012
72a91d0
Add $generator->close() method
nikic May 29, 2012
bc08c2c
Add support for yielding keys
nikic May 30, 2012
8790160
Add auto-increment keys
nikic May 30, 2012
0033a52
Allow throwing exceptions from generators
nikic May 30, 2012
ee89e22
Allow yielding during function calls
nikic May 30, 2012
1477be9
Make $generator->send() return the current value
nikic May 31, 2012
6117f4c
Add cloning support for generators
nikic Jun 2, 2012
7b3bfa5
Improve backtraces from generators
nikic Jun 3, 2012
bf82f46
Properly handle yield during method calls
nikic Jun 3, 2012
40760ec
Fix cloning of generator methods
nikic Jun 3, 2012
f169b26
Fix backtraces and func_get_args()
nikic Jun 8, 2012
d939d2d
Add sceleton for yield* expression
nikic Jun 11, 2012
6233408
Fix thread safe build
nikic Jun 20, 2012
1d3f37d
Fix segfault in method test
nikic Jun 22, 2012
04e781f
Implement get_iterator
nikic Jun 22, 2012
14766e1
Pass zend_generator directly to Zend VM
nikic Jun 23, 2012
ab75ed6
Disallow closing a generator during its execution
nikic Jun 23, 2012
5a9bddb
Forgot to git add two tests
nikic Jun 25, 2012
85f077c
Add support by yielding by-reference
nikic Jul 17, 2012
c9709bf
Remove asterix modifier (*) for generators
nikic Jul 19, 2012
612c249
Move a variable
nikic Jul 20, 2012
1f70a4c
Add some more tests
nikic Jul 20, 2012
8074863
Require parenthesis around yield expressions
nikic Jul 21, 2012
de80e3c
Remove reference restrictions from foreach
nikic Jul 22, 2012
94b2cca
Fix throwing of exceptions within a generator
nikic Jul 22, 2012
1340893
Throw error also for return occuring before yield
nikic Jul 22, 2012
99f93dd
Add T_YIELD in tokenizer_data.c
nikic Jul 22, 2012
268740d
Fix implementation of Iterator interface
nikic Jul 26, 2012
f4ce364
Merge remote-tracking branch 'php-src/master' into addGeneratorsSupport
nikic Aug 13, 2012
ae71693
Support trivial finally in generators (no yield, no return)
nikic Aug 13, 2012
7195a5b
Forgot to add test
nikic Aug 13, 2012
05f1048
Drop Generator::close() method
nikic Aug 20, 2012
9003cd1
Fix zts build (typo)
nikic Aug 20, 2012
1823b16
Merge remote-tracking branch 'php-src/master' into addGeneratorsSupport
nikic Aug 20, 2012
f45a0f3
Disallow serialization and unserialization
nikic Aug 20, 2012
6517ed0
Merge remote-tracking branch 'php-src/master' into addGeneratorsSupport
nikic Aug 24, 2012
68c1e1c
Add dedicated opcode for returns from a generator
nikic Aug 24, 2012
7cdf636
Finally with return now works in generators too
nikic Aug 24, 2012
4d8edda
Run finally if generator is closed before finishing
nikic Aug 24, 2012
f53225a
Fix several issues and allow rewind only at/before first yield
nikic Aug 25, 2012
bd70d15
Remove implementation stubs for yield delegation
nikic Aug 25, 2012
d60e3c6
Merge remote-tracking branch 'php-src/master' into addGeneratorsSupport
nikic Aug 25, 2012
cc07038
Make sure that exception is thrown on rewind() after closing too
nikic Aug 29, 2012
bef7958
Fix segfault when traversing a by-ref generator twice
nikic Aug 29, 2012
dbc7809
Fix typos
nikic Aug 29, 2012
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Support trivial finally in generators (no yield, no return)
The finally clause is now properly run when an exception is thrown in the
try-block. It is not yet run on `return` and also not run when the generator
is claused within a try block.

I'll add those two things as soon as laruence refactored the finally code.
  • Loading branch information
nikic committed Aug 13, 2012
commit ae716939eb500f962336d37b96069cb7452c25df
24 changes: 12 additions & 12 deletions Zend/zend_vm_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -2513,6 +2513,18 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
zend_bool nested;
zend_op_array *op_array = EX(op_array);

/* Generators go throw a different cleanup process */
if (EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) {
/* The generator object is stored in return_value_ptr_ptr */
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);

/* Close the generator to free up resources */
zend_generator_close(generator, 1 TSRMLS_CC);

/* Pass execution back to handling code */
ZEND_VM_RETURN();
}

EG(current_execute_data) = EX(prev_execute_data);
EG(opline_ptr) = NULL;
if (!EG(active_symbol_table)) {
Expand Down Expand Up @@ -5213,18 +5225,6 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
ZEND_VM_CONTINUE();
} else {
/* For generators skip the leave handler and return directly */
if (EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) {
/* The generator object is stored in return_value_ptr_ptr */
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);

/* Close the generator to free up resources */
zend_generator_close(generator, 1 TSRMLS_CC);

/* Pass execution back to handling code */
ZEND_VM_RETURN();
}

ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
}
}
Expand Down
24 changes: 12 additions & 12 deletions Zend/zend_vm_execute.h
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,18 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
zend_bool nested;
zend_op_array *op_array = EX(op_array);

/* Generators go throw a different cleanup process */
if (EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) {
/* The generator object is stored in return_value_ptr_ptr */
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);

/* Close the generator to free up resources */
zend_generator_close(generator, 1 TSRMLS_CC);

/* Pass execution back to handling code */
ZEND_VM_RETURN();
}

EG(current_execute_data) = EX(prev_execute_data);
EG(opline_ptr) = NULL;
if (!EG(active_symbol_table)) {
Expand Down Expand Up @@ -1177,18 +1189,6 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
ZEND_VM_CONTINUE();
} else {
/* For generators skip the leave handler and return directly */
if (EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) {
/* The generator object is stored in return_value_ptr_ptr */
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);

/* Close the generator to free up resources */
zend_generator_close(generator, 1 TSRMLS_CC);

/* Pass execution back to handling code */
ZEND_VM_RETURN();
}

return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
}
Expand Down