Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
php-pulls merged 74 commits intophp:masterfromnikic:addGeneratorsSupport
Sep 1, 2012
Merged

Conversation

nikic
Copy link
Member

PR for generators as outlined inhttps://wiki.php.net/rfc/generators.

(For the diff)

nikic added30 commitsMay 15, 2012 18:30
Generator functions have to specify the * (asterix) modifier after thefunction keyword. If they do so the ZEND_ACC_GENERATOR flag is added tothe fn_flags.
The block for the foreach separator was nested unnecessary. This commitsimply removes that nesting.
The yield statement can only be used in generator functions, which aremarked with an asterix.
The execution of generator functions will be suspended right after thearguments were RECVed. This will be done in zend_do_suspend_if_generator.
If the function is a generator this opcode will be invoked right afterreceiving the function arguments.The current implementation is just a dummy.
The Generator class now uses a zend_generator struct, so it'll be able tostore additional info.This commit also ensures that Generator cannot be directly instantiatedand extended. The error tests are now in a separate folder from the(yet-to-come) functional tests.
Right now generator functions simply immediately return a new Generatorobject (no suspension yet).
Generators need to switch the execute_data very often. If the execute_datais allocated on the VM stack this operation would require to always copythe structure (which is quite large). That's why the execution context isallocated on the heap instead (only for generators obviously).
This is just some initial code, which is still quite broken (and needs to bemoved so it can be reused.)
This simply adds dummy rewind/valid/current/key/next methods to Generator.
Before one could only call it with cwd=Zend.
This adds another function execute_ex(), which accepts a zend_execute_datastruct to run (contrary to execute(), which accepts a zend_op_array fromwhich it initialized the execute_data).This needs a bit more cleanup.
The generator zval is put into the return_value_ptr_ptr.
For generators ZEND_RETURN directly calls ZEND_VM_RETURN(), thus passingexecution back to the caller (zend_generator_resume).This commit also adds a check that only return; is used in generators andnot return $value;.
The test implements an xrange() function (the generator version of range()).
If the generator is closed before it has finished running, it may happenthat some FREE or SWITCH_FREE opcodes haven't been executed and memory isleaked.This fixes it by walking the brk_cont_array and manually freeing thevariables.
This happens primarily when the generator is invoked from some internalplace like a dynamic function call.
This fixes several issues. In particular it makes method generators workproperly and also allows generators using a symbol table.
To keep things clean two new functions are introduced:zend_clean_and_cache_symbol_table(HashTable *symbol_table)zend_free_compiled_variables(zval ***CVs, int num)
Yield now is an expression and the return value is the value passed to$generator->send(). By default (i.e. if ->next() is called) the value isNULL.Unlike in Python ->send() can be run without priming the generator with a->next() call first.
If the generator is used as a coroutine it often doesn't make sense to yieldanything. In this case one can simply receive values using    $value = yield;The yield here will simply yield NULL.
Calling $generator->close() is equivalent to executing a return statementat the current position in the generator.
This is just an intial merge. It does not yet make generators and finallywork together.Conflicts:Zend/zend_language_scanner.cZend/zend_language_scanner_defs.hZend/zend_vm_def.hZend/zend_vm_execute.hZend/zend_vm_execute.sklZend/zend_vm_opcodes.h
The finally clause is now properly run when an exception is thrown in thetry-block. It is not yet run on `return` and also not run when the generatoris claused within a try block.I'll add those two things as soon as laruence refactored the finally code.
Merging master to fix Windows buildConflicts:Zend/zend_language_scanner.cZend/zend_language_scanner_defs.hZend/zend_vm_def.h
Conflicts:Zend/zend_vm_def.hZend/zend_vm_execute.h
Generators don't have a return value, so it doesn't make sense to havea shared implementation here.
 * Trying to resume a generator while it is already running now throws a   fatal error. * Trying to use yield in finally while the generator is being force-closed   (by GC) throws a fatal error. * Rewinding after the first yield now throws an Exception
@laruence
Copy link
Member

Now I get the diff, thanks

I decided to leave out yield delegation for an initial proposal, so removethe stubs for it too.
Conflicts:Zend/zend_language_parser.yZend/zend_vm_execute.skl
@@ -1,12 +0,0 @@
--TEST--
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

why delete this test?

If you try to traverse an already closed generator an exception will now bethrown.Furthermore this changes the error for traversing a by-val generator by-reffrom an E_ERROR to an Exception.
@travisbot
Copy link

This pull requestfails (mergeddbc7809 into35951d4).

@php-pullsphp-pulls merged commitdbc7809 intophp:masterSep 1, 2012
@KendallHopkins
Copy link

@nikic I'm getting segfaults with this codehttps://gist.github.com/3588986

@smalyshev
Copy link
Contributor

@KendallHopkins please submit a bug report to bugs.php.net so it could be tracked properly.

@KendallHopkins
Copy link

@@ -1845,17 +1845,22 @@
zend_bool nested;
zend_op_array *op_array = EX(op_array);

/* Generators go throw a different cleanup process */

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Through? 😄

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers
No reviews
Assignees
No one assigned
Labels
None yet
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

8 participants
@nikic@laruence@travisbot@KendallHopkins@smalyshev@reeze@bradfeehan@php-pulls

[8]ページ先頭

©2009-2025 Movatter.jp