summaryrefslogtreecommitdiff
path: root/Zend
Commit message (Collapse)AuthorAgeFilesLines
...
* | | Merge branch 'generators'Gustavo Lopes2012-09-0173-2787/+9313
|\ \ \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * generators: (70 commits) Fix typos Fix segfault when traversing a by-ref generator twice Make sure that exception is thrown on rewind() after closing too Remove implementation stubs for yield delegation Fix several issues and allow rewind only at/before first yield Run finally if generator is closed before finishing Finally with return now works in generators too Add dedicated opcode for returns from a generator Disallow serialization and unserialization Fix zts build (typo) Drop Generator::close() method Forgot to add test Support trivial finally in generators (no yield, no return) Fix implementation of Iterator interface Add T_YIELD in tokenizer_data.c Throw error also for return occuring before yield Fix throwing of exceptions within a generator Remove reference restrictions from foreach Require parenthesis around yield expressions Add some more tests ...
| * | | Fix typosNikita Popov2012-08-291-3/+3
| | | |
| * | | Fix segfault when traversing a by-ref generator twiceNikita Popov2012-08-293-10/+24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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-292-1/+17
| | | |
| * | | Merge remote-tracking branch 'php-src/master' into addGeneratorsSupportNikita Popov2012-08-267-75/+128
| |\ \ \ | | | | | | | | | | | | | | | | | | | | | | | | | Conflicts: Zend/zend_language_parser.y Zend/zend_vm_execute.skl
| * | | | Remove implementation stubs for yield delegationNikita Popov2012-08-256-80/+2
| | | | | | | | | | | | | | | | | | | | | | | | | I decided to leave out yield delegation for an initial proposal, so remove the stubs for it too.
| * | | | Fix several issues and allow rewind only at/before first yieldNikita Popov2012-08-258-13/+269
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * 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-243-1/+60
| | | | |
| * | | | Finally with return now works in generators tooNikita Popov2012-08-241-0/+33
| | | | |
| * | | | Add dedicated opcode for returns from a generatorNikita Popov2012-08-244-58/+44
| | | | | | | | | | | | | | | | | | | | | | | | | Generators don't have a return value, so it doesn't make sense to have a shared implementation here.
| * | | | Merge remote-tracking branch 'php-src/master' into addGeneratorsSupportNikita Popov2012-08-2427-856/+840
| |\ \ \ \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Conflicts: Zend/zend_vm_def.h Zend/zend_vm_execute.h
| * | | | | Disallow serialization and unserializationNikita Popov2012-08-202-6/+72
| | | | | |
| * | | | | Merge remote-tracking branch 'php-src/master' into addGeneratorsSupportNikita Popov2012-08-2023-1255/+1430
| |\ \ \ \ \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Merging master to fix Windows build Conflicts: Zend/zend_language_scanner.c Zend/zend_language_scanner_defs.h Zend/zend_vm_def.h
| * | | | | | Fix zts build (typo)Nikita Popov2012-08-201-1/+1
| | | | | | |
| * | | | | | Drop Generator::close() methodNikita Popov2012-08-209-94/+6
| | | | | | |
| * | | | | | Forgot to add testNikita Popov2012-08-131-0/+28
| | | | | | |
| * | | | | | Support trivial finally in generators (no yield, no return)Nikita Popov2012-08-132-24/+24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
| * | | | | | Merge remote-tracking branch 'php-src/master' into addGeneratorsSupportNikita Popov2012-08-1361-24179/+3766
| |\ \ \ \ \ \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is just an intial merge. It does not yet make generators and finally work together. Conflicts: Zend/zend_language_scanner.c Zend/zend_language_scanner_defs.h Zend/zend_vm_def.h Zend/zend_vm_execute.h Zend/zend_vm_execute.skl Zend/zend_vm_opcodes.h
| * | | | | | | Fix implementation of Iterator interfaceNikita Popov2012-07-262-1/+40
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 ;)
| * | | | | | | Throw error also for return occuring before yieldNikita Popov2012-07-224-8/+28
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Previously only an error was thrown when return occured after yield. Also returns before the first yield would fail for by-ref generators. Now the error message is handled in pass_two, so all returns are checked.
| * | | | | | | Fix throwing of exceptions within a generatorNikita Popov2012-07-225-6/+32
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 reference restrictions from foreachNikita Popov2012-07-225-23/+37
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | foreach only allowed variables to be traversed by reference. This never really made sense because a) Expressions like array(&$a, &$b) can be meaningfully iterated by-ref b) Function calls can return by-ref (so they can also be meaningfully iterated) c) Iterators could at least in theory also be iterated by-ref (not sure if any iterator makes use of this) With by-ref generators the restriction makes even less sense, so I removed it altogether.
| * | | | | | | Require parenthesis around yield expressionsNikita Popov2012-07-226-47/+109
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If yield is used in an expression context parenthesis are now required. This ensures that the code is unambiguos. Yield statements can still be used without parenthesis (which should be the most common case). Also yield expressions without value can be used without parenthesis, too (this should be the most common case for coroutines). If the yield expression is used in a context where parenthesis are required anyway, no additional parenthesis have to be inserted. Examples: // Statements don't need parenthesis yield $foo; yield $foo => $bar; // Yield without value doesn't need parenthesis either $data = yield; // Parentheses don't have to be duplicated foo(yield $bar); if (yield $bar) { ... } // But we have to use parentheses here $foo = (yield $bar); This commit also fixes an issue with by-ref passing of $foo[0] like variables. They previously weren't properly fetched for write. Additionally this fixes valgrind warnings which were caused by access to uninitialized memory in zend_is_function_or_method_call().
| * | | | | | | Add some more testsNikita Popov2012-07-204-0/+105
| | | | | | | |
| * | | | | | | Move a variableNikita Popov2012-07-202-26/+52
| | | | | | | |
| * | | | | | | Remove asterix modifier (*) for generatorsNikita Popov2012-07-2045-324/+247
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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-1710-439/+1746
| | | | | | | |
| * | | | | | | Forgot to git add two testsNikita Popov2012-06-252-0/+42
| | | | | | | |
| * | | | | | | Disallow closing a generator during its executionNikita Popov2012-06-232-0/+17
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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-233-84/+79
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 segfault in method testNikita Popov2012-06-232-6/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A ref has to be added to $this if the generator is called !nested (which is the case when it is invoked via getIterator).
| * | | | | | | Fix thread safe buildNikita Popov2012-06-205-10/+10
| | | | | | | |
| * | | | | | | Add sceleton for yield* expressionNikita Popov2012-06-1911-7/+80
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This does not yet actually implement any delegation.
| * | | | | | | Fix backtraces and func_get_args()Nikita Popov2012-06-096-58/+149
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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-052-0/+28
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Forgot to add a reference to the this variable
| * | | | | | | Properly handle yield during method callsNikita Popov2012-06-032-0/+43
| | | | | | | |
| * | | | | | | Improve backtraces from generatorsNikita Popov2012-06-032-0/+29
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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-025-9/+243
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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-312-1/+25
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This makes the API easier to use (and is consistent with Python and JS).
| * | | | | | | Allow yielding during function callsNikita Popov2012-05-316-10/+102
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
| * | | | | | | Allow throwing exceptions from generatorsNikita Popov2012-05-303-16/+100
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The missing piece is how one can find the next stack frame, which is required for dtor'ing arguments pushed to the stack. As the generator execute_data does not live on the stack one can't use it to figure out the start of the next stack frame. So there must be some other method.
| * | | | | | | Add auto-increment keysNikita Popov2012-05-305-78/+313
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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-308-319/+2448
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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-292-0/+49
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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-292-0/+19
| | | | | | | |
| * | | | | | | Allow to use yield without valueNikita Popov2012-05-295-18/+127
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If the generator is used as a coroutine it often doesn't make sense to yield anything. In this case one can simply receive values using $value = yield; The yield here will simply yield NULL.
| * | | | | | | Add support for $generator->send()Nikita Popov2012-05-298-9/+115
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
| * | | | | | | Make the GOTO and SWITCH VMs work againNikita Popov2012-05-294-13/+41
| | | | | | | |
| * | | | | | | Properly free resources when generator return value not usedNikita Popov2012-05-286-60/+60
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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)