summaryrefslogtreecommitdiff
path: root/Zend/zend_generators.c
Commit message (Collapse)AuthorAgeFilesLines
* Happy New YearXinchen Hui2013-01-011-1/+1
|
* Implement Generator::throw() methodNikita Popov2012-12-241-5/+44
| | | | | | | Generator::throw($exception) throws an exception into the generator. The exception is thrown at the current point of suspension within the generator. It basically behaves as if the current yield statement were replaced with a throw statement and the generator subsequently resumed.
* Fix crash when last yielded value is a closureNikita Popov2012-12-211-10/+10
| | | | | | | | | | | | If zend_generator_close is called from within zend_generator_resume (e.g. due to a return statement) then all the EGs will still be using the values from the generator. That's why the stack frame has to be the last thing that is dtored, otherwise some other dtor that is using EG(current_execute_data) might access the already freed memory segment. This was the case with the closure dtor. The fix is to move the dtors for key and value to the start of the handler. This way the stack frame is the last thing that is freed.
* Do not add a ref to EX(object) on generator cloneNikita Popov2012-12-201-5/+1
| | | | | If a ref has to be added it will be already added while walking the call slots.
* Fix leak when generator ignores sent valueNikita Popov2012-12-181-8/+3
| | | | | | | When the return value of yield wasn't used it was leaked. This is fixed by using a TMP_VAR return value instead of VAR. TMP_VARs are automatically freed when they aren't used.
* Fix warning of no return in non-void functionXinchen Hui2012-12-141-0/+1
|
* Restored proper generators behaviour in conjunction with "finally". (Nikita)Dmitry Stogov2012-12-121-2/+36
|
* - generators API exported for extensionsDmitry Stogov2012-12-111-3/+3
| | | | - improved RETURN sequence to avoid redundant check if op_array is a generator
* Optimized access to temporary and compiled VM variablesDmitry Stogov2012-12-041-17/+15
|
* - Fixed ZTS buildFelipe Pena2012-11-301-1/+1
|
* . The VM stacks for passing function arguments and syntaticaly nested calls ↵Dmitry Stogov2012-11-301-206/+98
| | | | | | were merged into a single stack. The stack size needed for op_array execution is calculated at compile time and preallocated at once. As result all the stack push operatins don't require checks for stack overflow any more. . Generators implementation was improved using the new VM stack. Now it's a bit more clear and faster.
* Fix bug #63596: finally in generators segfaultsNikita Popov2012-11-241-0/+1
| | | | | EX(fast_ret) wasn't initialized in this case so the code ended up dereferencing an invalid pointer after the jump.
* Improved "finally" im[plementationDmitry Stogov2012-11-221-1/+0
|
* Fixed bug #63428 (The behavior of execute() changed)Xinchen Hui2012-11-041-0/+4
|
* Fixed bug #63132Nikita Popov2012-09-221-0/+57
| | | | | | | | | | | | | | EG(arg_types_stack) is now also backed up when generators are used. This allows the use of yield in nested method calls. This commit adds two new functions to the zend_ptr_stack API: zend_ptr_stack_push_from_memory zend_ptr_stack_pop_into_memory both taking the following arguments: zend_ptr_stack *stack, int count, void **pointers
* Fix two op_array -> function cast warningsNikita Popov2012-09-161-1/+1
|
* - fix build, declarations must be 1st in a contextgit checkout -f masterPierre Joye2012-09-051-3/+6
|
* Fixed bug #62991 (Segfault with generator and closure)Dmitry Stogov2012-09-051-0/+14
|
* Fix typosNikita Popov2012-08-291-3/+3
|
* Fix segfault when traversing a by-ref generator twiceNikita Popov2012-08-291-1/+7
| | | | | | | | If you try to traverse an already closed generator an exception will now be thrown. Furthermore this changes the error for traversing a by-val generator by-ref from an E_ERROR to an Exception.
* Make sure that exception is thrown on rewind() after closing tooNikita Popov2012-08-291-1/+1
|
* Fix several issues and allow rewind only at/before first yieldNikita Popov2012-08-251-10/+39
| | | | | | | | * 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
* Run finally if generator is closed before finishingNikita Popov2012-08-241-1/+34
|
* Disallow serialization and unserializationNikita Popov2012-08-201-6/+26
|
* Drop Generator::close() methodNikita Popov2012-08-201-30/+0
|
* Fix implementation of Iterator interfaceNikita Popov2012-07-261-1/+3
| | | | | | | | | It looks like you have to implement the Iterator interface *before* assigning get_iterator. Otherwise the structure for user iterators isn't correctly zeroed out. Additionaly I'm setting class_entry->iterator_funcs.funcs now. Not sure if this is strictly necessary, but better safe than sorry ;)
* Fix throwing of exceptions within a generatorNikita Popov2012-07-221-3/+9
| | | | | | If a generator threw an exception and was iterated using foreach (i.e. not manually) an infinite loop was triggered. The reason was that the exception was not properly rethrown using zend_throw_exception_internal.
* Remove asterix modifier (*) for generatorsNikita Popov2012-07-201-3/+50
| | | | | | | | | | | | | | | | Generators are now automatically detected by the presence of a `yield` expression in their body. This removes the ZEND_SUSPEND_AND_RETURN_GENERATOR opcode. Instead additional checks for ZEND_ACC_GENERATOR are added to the fcall_common helper and zend_call_function. This also adds a new function zend_generator_create_zval, which handles the actual creation of the generator zval from an op array. I feel like I should deglobalize the zend_create_execute_data_from_op_array code a bit. It currently changes EG(current_execute_data) and EG(opline_ptr) which is somewhat confusing (given the name).
* Add support by yielding by-referenceNikita Popov2012-07-171-4/+4
|
* Disallow closing a generator during its executionNikita Popov2012-06-231-0/+13
| | | | | If a generator is closed while it is running an E_WARNING is thrown and the call is ignored. Maybe a fatal error should be thrown instead?
* Pass zend_generator directly to Zend VMNikita Popov2012-06-231-49/+44
| | | | | | Previously the zval* of the generator was passed into the VM by misusing EG(return_value_ptr_ptr). Now the zend_generator* itself is directly passed in. This saves us from always having to pass the zval* around everywhere.
* Implement get_iteratorNikita Popov2012-06-231-0/+109
| | | | | This implements the get_iterator handler for Generator objects, thus making direct foreach() iteration significantly faster.
* Fix thread safe buildNikita Popov2012-06-201-2/+2
|
* Add sceleton for yield* expressionNikita Popov2012-06-191-2/+1
| | | | This does not yet actually implement any delegation.
* Fix backtraces and func_get_args()Nikita Popov2012-06-091-3/+41
| | | | | | | | | | | | To make the generator function show up in backtraces one has to insert an additional execute_data into the chain, as prev_execute_data->function_state is used to determine the called function. Adding the additional stack frame is also required for func_get_args(), as the arguments are fetched from there too. The arguments have to be copied in order to keep them around. Due to the way they are saved doing so is quite ugly, so I added another function zend_copy_arguments to zend_execute.c which handles this.
* Fix cloning of generator methodsNikita Popov2012-06-051-0/+4
| | | | Forgot to add a reference to the this variable
* Properly handle yield during method callsNikita Popov2012-06-031-0/+8
|
* Improve backtraces from generatorsNikita Popov2012-06-031-0/+4
| | | | | | | | The current situation is still not perfect, as the generator function itself does not appear in the stack trace. This makes sense in some way, but it would probably be more helpful if it would show up (with the bound arguments) after the $generator->xyz() call. This could be misleading too though as the function is not *really* called there.
* Add cloning support for generatorsNikita Popov2012-06-021-9/+133
| | | | | | Generators can now be cloned. I'm pretty sure that my current code does not yet cover all the edge cases of cloning the execution context, so there are probably a few bugs in there :)
* Make $generator->send() return the current valueNikita Popov2012-05-311-1/+5
| | | | This makes the API easier to use (and is consistent with Python and JS).
* Allow yielding during function callsNikita Popov2012-05-311-0/+33
| | | | | | | | During function calls arguments are pushed onto the stack. Now these are backed up on yield and restored on resume. This requires memcpy'ing them, but there doesn't seem to be any better way to do it. Also this fixes the issue with exceptions thrown during function calls.
* Add auto-increment keysNikita Popov2012-05-301-0/+3
| | | | | | When no key is explicitely yielded PHP will used auto-incrementing keys as a fallback. They behave the same as with arrays, i.e. the key is the successor of the largest previously used integer key.
* Add support for yielding keysNikita Popov2012-05-301-0/+8
| | | | | | | | | | | | | | | | | | | | | Keys are yielded using the yield $key => $value syntax. Currently this is implemented as a statement only and not as an expression, because conflicts arise considering nesting and use in arrays: yield yield $a => $b; // could be either yield (yield $a) => $b; // or yield (yield $a => $b); Once I find some way to resolve these conflicts this should be available as an expression too. Also the key yielding code is rather copy-and-past-y for the value yielding code, so that should be factored out.
* Add $generator->close() methodNikita Popov2012-05-291-0/+17
| | | | | Calling $generator->close() is equivalent to executing a return statement at the current position in the generator.
* Fix segfault when send()ing to a closed generatorNikita Popov2012-05-291-0/+5
|
* Add support for $generator->send()Nikita Popov2012-05-291-0/+32
| | | | | | | | | 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 is NULL. Unlike in Python ->send() can be run without priming the generator with a ->next() call first.
* Properly free resources when generator return value not usedNikita Popov2012-05-281-6/+1
| | | | | | | 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)
* Set EG(current_execute_data)Nikita Popov2012-05-281-0/+3
| | | | | This fixes several issues. In particular it makes method generators work properly and also allows generators using a symbol table.
* Free loop variablesNikita Popov2012-05-271-2/+38
| | | | | | | | | If the generator is closed before it has finished running, it may happen that some FREE or SWITCH_FREE opcodes haven't been executed and memory is leaked. This fixes it by walking the brk_cont_array and manually freeing the variables.
* Add support for generator methodsNikita Popov2012-05-271-22/+41
|