-
Notifications
You must be signed in to change notification settings - Fork 7.9k
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
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 252f623
Add flag for generator functions
nikic 9b51a3b
Minor code cleanup
nikic fd2a109
Add error if yield is used outside a generator
nikic e14cfaf
Add zend_do_suspend_if_generator calls
nikic 1cec3f1
Add ZEND_SUSPEND_AND_RETURN_GENERATOR opcode
nikic ca59e54
Add empty Generator class
nikic 40b7533
Add some boilerplate code for Generator class
nikic 46fa26a
Make generator functions return a Generator object
nikic 5e763d9
Allocate execute_data using malloc for generators
nikic 9ce9a7e
Add initial code for suspending execution
nikic 2c5ecb4
Add dummy Iterator implementation
nikic ececcbc
Allow calling zend_vm_gen from everywhere
nikic f627be5
Add support for executing a zend_execute_data
nikic 1a99d1c
Add way to pass generator object to opcode handlers
nikic fafce58
Add YIELD opcode implementation
nikic 5bb3a99
Implement return for generators
nikic d49d397
Close generator on return
nikic cbfa96c
Remove wrong dtor call
nikic 39d3d5e
Add first real generator test
nikic 247bb73
Add support for generator methods
nikic 64a643a
Free loop variables
nikic 9f52c5c
Fix generator creation when execute_data is not nested
nikic bcc7d97
Set EG(current_execute_data)
nikic 4aab08b
Properly free resources when generator return value not used
nikic b770b22
Make the GOTO and SWITCH VMs work again
nikic 3600914
Add support for $generator->send()
nikic ad525c2
Allow to use yield without value
nikic 12e9283
Fix segfault when send()ing to a closed generator
nikic 72a91d0
Add $generator->close() method
nikic bc08c2c
Add support for yielding keys
nikic 8790160
Add auto-increment keys
nikic 0033a52
Allow throwing exceptions from generators
nikic ee89e22
Allow yielding during function calls
nikic 1477be9
Make $generator->send() return the current value
nikic 6117f4c
Add cloning support for generators
nikic 7b3bfa5
Improve backtraces from generators
nikic bf82f46
Properly handle yield during method calls
nikic 40760ec
Fix cloning of generator methods
nikic f169b26
Fix backtraces and func_get_args()
nikic d939d2d
Add sceleton for yield* expression
nikic 6233408
Fix thread safe build
nikic 1d3f37d
Fix segfault in method test
nikic 04e781f
Implement get_iterator
nikic 14766e1
Pass zend_generator directly to Zend VM
nikic ab75ed6
Disallow closing a generator during its execution
nikic 5a9bddb
Forgot to git add two tests
nikic 85f077c
Add support by yielding by-reference
nikic c9709bf
Remove asterix modifier (*) for generators
nikic 612c249
Move a variable
nikic 1f70a4c
Add some more tests
nikic 8074863
Require parenthesis around yield expressions
nikic de80e3c
Remove reference restrictions from foreach
nikic 94b2cca
Fix throwing of exceptions within a generator
nikic 1340893
Throw error also for return occuring before yield
nikic 99f93dd
Add T_YIELD in tokenizer_data.c
nikic 268740d
Fix implementation of Iterator interface
nikic f4ce364
Merge remote-tracking branch 'php-src/master' into addGeneratorsSupport
nikic ae71693
Support trivial finally in generators (no yield, no return)
nikic 7195a5b
Forgot to add test
nikic 05f1048
Drop Generator::close() method
nikic 9003cd1
Fix zts build (typo)
nikic 1823b16
Merge remote-tracking branch 'php-src/master' into addGeneratorsSupport
nikic f45a0f3
Disallow serialization and unserialization
nikic 6517ed0
Merge remote-tracking branch 'php-src/master' into addGeneratorsSupport
nikic 68c1e1c
Add dedicated opcode for returns from a generator
nikic 7cdf636
Finally with return now works in generators too
nikic 4d8edda
Run finally if generator is closed before finishing
nikic f53225a
Fix several issues and allow rewind only at/before first yield
nikic bd70d15
Remove implementation stubs for yield delegation
nikic d60e3c6
Merge remote-tracking branch 'php-src/master' into addGeneratorsSupport
nikic cc07038
Make sure that exception is thrown on rewind() after closing too
nikic bef7958
Fix segfault when traversing a by-ref generator twice
nikic dbc7809
Fix typos
nikic File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Disallow serialization and unserialization
- Loading branch information
commit f45a0f31c8354947c0e2b9ea44a63fc0a2c23a01
There are no files selected for viewing
46 changes: 46 additions & 0 deletions
46
Zend/tests/generators/errors/serialize_unserialize_error.phpt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
--TEST-- | ||
Generators can't be serialized or unserialized | ||
--FILE-- | ||
<?php | ||
|
||
function gen() { yield; } | ||
|
||
$gen = gen(); | ||
|
||
try { | ||
serialize($gen); | ||
} catch (Exception $e) { | ||
echo $e, "\n\n"; | ||
} | ||
|
||
try { | ||
var_dump(unserialize('O:9:"Generator":0:{}')); | ||
} catch (Exception $e) { | ||
echo $e, "\n\n"; | ||
} | ||
|
||
try { | ||
var_dump(unserialize('C:9:"Generator":0:{}')); | ||
} catch (Exception $e) { | ||
echo $e; | ||
} | ||
|
||
?> | ||
--EXPECTF-- | ||
exception 'Exception' with message 'Serialization of 'Generator' is not allowed' in %s:%d | ||
Stack trace: | ||
#0 %s(%d): serialize(Object(Generator)) | ||
#1 {main} | ||
|
||
exception 'Exception' with message 'Unserialization of 'Generator' is not allowed' in %s:%d | ||
Stack trace: | ||
#0 [internal function]: Generator->__wakeup() | ||
#1 %s(%d): unserialize('O:9:"Generator"...') | ||
#2 {main} | ||
|
||
|
||
Notice: unserialize(): Error at offset 19 of 20 bytes in %s on line %d | ||
exception 'Exception' with message 'Unserialization of 'Generator' is not allowed' in %s:%d | ||
Stack trace: | ||
#0 %s(%d): unserialize('C:9:"Generator"...') | ||
#1 {main} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -590,6 +590,23 @@ ZEND_METHOD(Generator, send) | |
} | ||
} | ||
|
||
|
||
/* {{{ proto void Generator::__wakeup | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. missing a '()' There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed |
||
* Throws an Exception as generators can't be serialized */ | ||
ZEND_METHOD(Generator, __wakeup) | ||
{ | ||
/* Just specifying the zend_class_unserialize_deny handler is not enough, | ||
* because it is only invoked for C unserialization. For O the error has | ||
* to be thrown in __wakeup. */ | ||
|
||
if (zend_parse_parameters_none() == FAILURE) { | ||
return; | ||
} | ||
|
||
zend_throw_exception(NULL, "Unserialization of 'Generator' is not allowed", 0 TSRMLS_CC); | ||
} | ||
/* }}} */ | ||
|
||
/* get_iterator implementation */ | ||
|
||
typedef struct _zend_generator_iterator { | ||
|
@@ -712,12 +729,13 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_generator_send, 0, 0, 1) | |
ZEND_END_ARG_INFO() | ||
|
||
static const zend_function_entry generator_functions[] = { | ||
ZEND_ME(Generator, rewind, arginfo_generator_void, ZEND_ACC_PUBLIC) | ||
ZEND_ME(Generator, valid, arginfo_generator_void, ZEND_ACC_PUBLIC) | ||
ZEND_ME(Generator, current, arginfo_generator_void, ZEND_ACC_PUBLIC) | ||
ZEND_ME(Generator, key, arginfo_generator_void, ZEND_ACC_PUBLIC) | ||
ZEND_ME(Generator, next, arginfo_generator_void, ZEND_ACC_PUBLIC) | ||
ZEND_ME(Generator, send, arginfo_generator_send, ZEND_ACC_PUBLIC) | ||
ZEND_ME(Generator, rewind, arginfo_generator_void, ZEND_ACC_PUBLIC) | ||
ZEND_ME(Generator, valid, arginfo_generator_void, ZEND_ACC_PUBLIC) | ||
ZEND_ME(Generator, current, arginfo_generator_void, ZEND_ACC_PUBLIC) | ||
ZEND_ME(Generator, key, arginfo_generator_void, ZEND_ACC_PUBLIC) | ||
ZEND_ME(Generator, next, arginfo_generator_void, ZEND_ACC_PUBLIC) | ||
ZEND_ME(Generator, send, arginfo_generator_send, ZEND_ACC_PUBLIC) | ||
ZEND_ME(Generator, __wakeup, arginfo_generator_void, ZEND_ACC_PUBLIC) | ||
ZEND_FE_END | ||
}; | ||
|
||
|
@@ -729,6 +747,8 @@ void zend_register_generator_ce(TSRMLS_D) /* {{{ */ | |
zend_ce_generator = zend_register_internal_class(&ce TSRMLS_CC); | ||
zend_ce_generator->ce_flags |= ZEND_ACC_FINAL_CLASS; | ||
zend_ce_generator->create_object = zend_generator_create; | ||
zend_ce_generator->serialize = zend_class_serialize_deny; | ||
zend_ce_generator->unserialize = zend_class_unserialize_deny; | ||
|
||
/* get_iterator has to be assigned *after* implementing the inferface */ | ||
zend_class_implements(zend_ce_generator TSRMLS_CC, 1, zend_ce_iterator); | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing a close folder comment /* }}} */ here :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed