Commit Graph

262 Commits

Author SHA1 Message Date
Dmitry Stogov
b1f53ca415 Use efree_size() instead of efree() where posible 2014-08-27 20:49:56 +04:00
Anatol Belski
6f9f0bf205 master renames phase 2 2014-08-25 19:28:33 +02:00
Dmitry Stogov
bce6a36c8a Merge branch 'master' into test
* master: (48 commits)
  change locale - looks like not everybody has sl_SI
  Fix bug #66921 - Wrong argument type hint for function intltz_from_date_time_zone
  fix format
  Fix bug #67052 (NumberFormatter::parse() resets LC_NUMERIC setting)
  Make sure the generator script also creates a newline at the end of file
  Add newline at end of file to prevent compilation warning
  Fix handling of session user module custom handlers.
  Reference bug report instead of github issue in NEWS file
  add more exts for Travis
  Update NEWS
  Fix phpdbg.1 man page installation when build != src directory
  BFN for bug #67551 (php://input temp file will be located in sys_temp_dir instead of upload_tmp_dir)
  reorder
  restore API compatibility
  finish
  refactor php_stream_temp_create{,_ex} and use it for the php://input stream
  refactor _php_stream_fopen_{temporary_,tmp}file()
  fix length overflow of HTTP_RAW_POST_DATA
  Update NEWS
  Fixed bug #67215 (php-cgi work with opcache, may be segmentation fault happen)
  ...

Conflicts:
	ext/opcache/zend_accelerator_util_funcs.c
	ext/session/mod_user.c
	ext/spl/spl_array.c
	ext/spl/spl_dllist.c
	ext/standard/file.c
	ext/standard/streamsfuncs.c
	ext/standard/string.c
	main/streams/memory.c
2014-07-07 19:21:23 +04:00
Dmitry Stogov
5aa91be509 Simplify call-frame handling 2014-07-07 15:50:44 +04:00
Dmitry Stogov
6bf24f4dd0 Removed EG(active_symbol_table) and use corresponding value from EG(current_execute_data) 2014-07-04 18:03:45 +04:00
Dmitry Stogov
c4d99ec982 Removed EG(called_scope) and use corresponding value from EG(current_execute_data) 2014-07-03 02:34:43 +04:00
Dmitry Stogov
63c057e331 Removed EG(opline_ptr) and use corresponding value from EG(current_execute_data) 2014-07-02 23:29:53 +04:00
Dmitry Stogov
4b09dd69e6 Removed EG(active_op_array) and use corresponding value from EG(current_execute_data) 2014-07-02 22:03:21 +04:00
Dmitry Stogov
412ad4b254 Uinified call frame handling for user and internal functions.
Now EG(current_execute_data) always point to the call frame of the currently executed function.
2014-07-02 22:01:25 +04:00
Nikita Popov
1ea4b17af2 Merge branch 'PHP-5.5' into PHP-5.6 2014-07-02 17:36:27 +02:00
Nikita Popov
d9ebd0f3d6 Fix bug #67497: eval with parse error causes segfault in generator 2014-07-02 17:33:31 +02:00
Dmitry Stogov
c69781393c Refactoring: merge call_frame and end_execute_data into single data structure. Keep only single copy of each argument on VM stack (previously ZE kept two copies of each arguments for user functions) 2014-06-26 23:51:14 +04:00
Dmitry Stogov
43477bc7a2 Refactoring: use call_frames instead of call_slots 2014-06-24 02:17:16 +04:00
Dmitry Stogov
c1965f58d4 Use reference counting instead of zval duplication 2014-06-05 16:04:11 +04:00
Xinchen Hui
bc357eaf3f Fixed apply_func_args_t 2014-05-25 20:04:35 +08:00
Dmitry Stogov
65e2ed6e50 Redesigned zend_execute_data layout now EX(object), EX(scope) and EX(called_scope) arr properties of the current function execution co
ntext. They are set during zend_execute_data initialization and never changed.
2014-04-24 15:53:20 +04:00
Dmitry Stogov
ea2e1bb1eb Optimized zend_leave_helper() 2014-04-18 13:46:36 +04:00
Dmitry Stogov
c99b767537 Fixed generator destruction 2014-04-09 10:47:03 +04:00
Dmitry Stogov
7402af380b Fixed destruction of objects and iterators on unclean request shutdown and GC (few cases are still unfixed).
Now we destroy objects it two steps. At first - object properties of all objects and only then the objects their selves.
2014-04-09 01:50:15 +04:00
Dmitry Stogov
ea85451b65 Refactored data structures to keep zend_object* instead of a whole zval in some places 2014-03-28 02:11:22 +04:00
Dmitry Stogov
24b72415cb Iterator has to be properly closed 2014-03-20 23:05:38 +04:00
Dmitry Stogov
b7938ab1bd Refactored GC (incomplete) 2014-03-19 17:00:28 +04:00
Dmitry Stogov
aa5f55306b Refactored EG(active_symbol_table) to be zend_array* instead of HashTable* 2014-03-17 23:15:22 +04:00
Dmitry Stogov
9ebd9388ee Fixed Generator::throw() 2014-03-06 00:45:53 +04:00
Xinchen Hui
a5ce7d526e Revert "Move zend_objects_store_put out of zend_object_std_init"
This reverts commit 8ced4f0ac9.
2014-02-28 13:59:07 +08:00
Xinchen Hui
8ced4f0ac9 Move zend_objects_store_put out of zend_object_std_init 2014-02-28 12:59:51 +08:00
Dmitry Stogov
3696e038e5 Various fixes related to read_property(), read_dimension() and iterators refactoring 2014-02-27 16:07:36 +04:00
Xinchen Hui
382b0dfdb7 Refactoring zend_iterator (incompleted) 2014-02-27 19:19:02 +08:00
Dmitry Stogov
495551aa8c Fixed iterators API. zend_iterator_init() has to be used in each get_iterator() callback. 2014-02-26 15:01:08 +04:00
Dmitry Stogov
d062fb3344 Generator related fixes 2014-02-26 13:58:59 +04:00
Dmitry Stogov
bb58ea348c Use better data structures (incomplete) 2014-02-18 18:10:54 +04:00
Dmitry Stogov
4e66abad54 Use better data structures (incomplete) - refactored return_value handling 2014-02-12 14:29:51 +04:00
Dmitry Stogov
f4cfaf36e2 Use better data structures (incomplete) 2014-02-10 10:04:30 +04:00
Xinchen Hui
c081ce628f Bump year 2014-01-03 11:08:10 +08:00
Xinchen Hui
47c9027772 Bump year 2014-01-03 11:06:16 +08:00
Nikita Popov
b3546e64bd Merge branch 'PHP-5.5' into PHP-5.6 2013-12-01 13:45:22 +01:00
Nikita Popov
02dca18b90 Fix bug #65764
I'm not exactly sure whether this is the right way to fix it. The
question is whether Generator::throw() on a newborn generator (i.e.
a generator that is not yet at yield expression) should first advance to
the first yield and throw the exception there or whether it should
instead throw the exception in the caller's context.

The old behavior was to throw it at the start of the function (i.e.
the very first opcode), which causes issues like the one in #65764.
Effectively it's impossible to properly handle the exceptions in this
case.

For now I choose the variant where the generator advances to the
first yield before throwing, as that's consistent with how all other
methods on the Generator object currently behave. This does not
necessarily match the behavior in other languages, e.g. Python would throw
the exception in the caller's context. But then our send() method already
has this kind of deviation, so it stays internally consistent at least.
2013-12-01 13:37:56 +01:00
Nikita Popov
e2a8d7dc17 Merge branch 'PHP-5.5' into PHP-5.6 2013-11-30 13:40:17 +01:00
Nikita Popov
b4f00be6c4 Cleanup generator closing code a bit
All code dealing with unfinished execution cleanup is now in a separate
function (previously most of it was run even when execution was properly
finished.

Furthermore some code dealing with unclean shutdowns has been removed,
which is no longer necessary, because we no longer try to clean up in
this case.
2013-11-30 13:38:21 +01:00
Nikita Popov
9589cae8cb Fixed bug #66041: list() fails to unpack yielded ArrayAccess object
Yield return values now use IS_VAR rather than IS_TMP_VAR. This
fixes the issue with list() and should also be faster as it avoids
doing a zval copy.
2013-11-30 13:08:31 +01:00
Nikita Popov
cbf0683c6f Merge branch 'PHP-5.5' 2013-09-29 20:19:40 +02:00
Nikita Popov
6b68f44e6b Fix bug #64979: Wrong behavior of static variables in closure generators 2013-09-29 20:18:12 +02:00
Nikita Popov
bdfa03d79d Save a TSRMLS_FETCH() for zval_ptr_dtor in executor
This gives me about 9% improvement on Zend/bench.php for a zts build.
2013-09-14 23:02:26 +02:00
Nikita Popov
47ee470992 Make use of direct returns in some places 2013-08-31 13:16:50 +02:00
Veres Lajos
6c4af15d6c typos (orig) 2013-07-15 00:19:32 -07:00
Veres Lajos
b8a2b254a1 typos (orig) 2013-07-15 00:18:32 -07:00
Nikita Popov
0f36224beb Don't try to clean up generator stack on unclean shutdown
This fixes bugs #65035 and #65161. In one of the bugs the issue is
that function_state.arguments is NULL, but the arg count is pushed
to the stack and the code tries to free it. In the other bug the
stack of the generator is freed twice, once in generator_close and
later during shutdown.

It's rather hard (if at all possible) to do a proper stack cleanup
on an unclean shutdown, so I'm just disabling it in this case.
2013-06-29 21:51:54 +02:00
Nikita Popov
8345abcabb Remove support for cloning generators 2013-03-29 11:42:10 +01:00
Nikita Popov
fcc6611de9 Add support for non-scalar Iterator keys in foreach
RFC: https://wiki.php.net/rfc/foreach-non-scalar-keys
2013-03-12 17:27:31 +01:00
Nikita Popov
114245c1b9 Fix bug #63830: Segfault on undefined function call in nested generator
This also reverses the destruction order of the pushed arguments to
align with how it is done everywhere else.

I'm not exactly sure whether this is the right way to fix it, but it
seems to work fine.
2013-02-01 19:53:04 +01:00
Nikita Popov
3ee20e450f Fix segfault when cloning generator with properties
Rule of thumb: Always implement the object clone handler rather
than the object storage clone handler. Actually I think we should
drop the latter. It's nearly never usable.
2013-02-01 18:33:26 +01:00
Nikita Popov
8b972efe5f Fix potential segfault when finally in a generator is run during shutdown
If a generator is destroyed in a finally block it will resume the generator to run that finally
block before freeing the generator. This was done in the object storage free handler.

Running user code in the free handler isn't safe though because the free handlers may be run
during request shutdown, already after several key components have been shut down.

This is avoided by doing the finally handling in the dtor handler. These handlers are run at the
start of the shutdown sequence.
2013-01-30 23:52:02 +01:00
Xinchen Hui
a666285bc2 Happy New Year 2013-01-01 16:37:09 +08:00
Nikita Popov
be7b0bc3ec Implement Generator::throw() method
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.
2012-12-24 00:27:55 +01:00
Nikita Popov
14f133036c Fix crash when last yielded value is a closure
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.
2012-12-21 17:28:20 +01:00
Nikita Popov
3e78c6ad25 Do not add a ref to EX(object) on generator clone
If a ref has to be added it will be already added while walking the call
slots.
2012-12-20 20:33:18 +01:00
Nikita Popov
d53f1bf8ab Fix leak when generator ignores sent value
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.
2012-12-18 21:39:02 +01:00
Xinchen Hui
a73a6be764 Fix warning of no return in non-void function 2012-12-14 17:26:42 +08:00
Dmitry Stogov
9c96fe52d9 Restored proper generators behaviour in conjunction with "finally". (Nikita) 2012-12-12 17:47:55 +04:00
Dmitry Stogov
a9a5f7aca6 - generators API exported for extensions
- improved RETURN sequence to avoid redundant check if op_array is a generator
2012-12-11 17:25:32 +04:00
Dmitry Stogov
7651d64556 Optimized access to temporary and compiled VM variables 2012-12-04 10:14:39 +04:00
Felipe Pena
5db372fbdc - Fixed ZTS build 2012-11-30 09:07:35 -02:00
Dmitry Stogov
70f83f35d0 . The VM stacks for passing function arguments and syntaticaly nested calls 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.
2012-11-30 13:39:23 +04:00
Nikita Popov
60871e51ad Fix bug #63596: finally in generators segfaults
EX(fast_ret) wasn't initialized in this case so the code ended up
dereferencing an invalid pointer after the jump.
2012-11-24 19:24:09 +01:00
Dmitry Stogov
eb4825b50b Improved "finally" im[plementation 2012-11-22 15:17:05 +04:00
Xinchen Hui
7bcb8780e0 Fixed bug #63428 (The behavior of execute() changed) 2012-11-04 12:48:35 +08:00
Nikita Popov
a31fa55b44 Fixed bug #63132
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
2012-09-22 19:15:53 +02:00
Nikita Popov
a47c11a13d Fix two op_array -> function cast warnings 2012-09-16 22:01:07 +02:00
Pierre Joye
4a7d1b4ed8 - fix build, declarations must be 1st in a contextgit checkout -f master 2012-09-05 12:53:29 +02:00
Dmitry Stogov
72473962a9 Fixed bug #62991 (Segfault with generator and closure) 2012-09-05 09:50:55 +04:00
Nikita Popov
dbc7809b17 Fix typos 2012-08-29 20:49:14 +02:00
Nikita Popov
bef79588d5 Fix segfault when traversing a by-ref generator twice
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.
2012-08-29 20:46:56 +02:00
Nikita Popov
cc07038fa9 Make sure that exception is thrown on rewind() after closing too 2012-08-29 20:31:34 +02:00
Nikita Popov
f53225a99e Fix several issues and allow rewind only at/before first yield
* 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
2012-08-25 17:40:08 +02:00
Nikita Popov
4d8edda341 Run finally if generator is closed before finishing 2012-08-24 19:10:09 +02:00
Nikita Popov
f45a0f31c8 Disallow serialization and unserialization 2012-08-20 16:01:16 +02:00
Nikita Popov
05f10480c5 Drop Generator::close() method 2012-08-20 12:53:18 +02:00
Nikita Popov
268740d984 Fix implementation of Iterator interface
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 ;)
2012-07-26 17:13:25 +02:00
Nikita Popov
94b2ccae9c Fix throwing of exceptions within a generator
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.
2012-07-22 17:46:46 +02:00
Nikita Popov
c9709bfbd7 Remove asterix modifier (*) for generators
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).
2012-07-20 16:09:06 +02:00
Nikita Popov
85f077cea1 Add support by yielding by-reference 2012-07-17 13:29:56 +02:00
Nikita Popov
ab75ed6ba9 Disallow closing a generator during its execution
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?
2012-06-23 16:08:15 +02:00
Nikita Popov
14766e1417 Pass zend_generator directly to Zend VM
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.
2012-06-23 14:43:52 +02:00
Nikita Popov
04e781f0e4 Implement get_iterator
This implements the get_iterator handler for Generator objects, thus making
direct foreach() iteration significantly faster.
2012-06-23 01:28:16 +02:00
Nikita Popov
6233408a2a Fix thread safe build 2012-06-20 21:31:23 +02:00
Nikita Popov
d939d2dee5 Add sceleton for yield* expression
This does not yet actually implement any delegation.
2012-06-19 00:37:31 +02:00
Nikita Popov
f169b26dd7 Fix backtraces and func_get_args()
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.
2012-06-09 00:40:47 +02:00
Nikita Popov
40760ecb90 Fix cloning of generator methods
Forgot to add a reference to the this variable
2012-06-05 14:00:31 +02:00
Nikita Popov
bf82f46ea9 Properly handle yield during method calls 2012-06-03 02:16:29 +02:00
Nikita Popov
7b3bfa5784 Improve backtraces from generators
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.
2012-06-03 02:00:11 +02:00
Nikita Popov
6117f4c7c0 Add cloning support for generators
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 :)
2012-06-02 20:40:58 +02:00
Nikita Popov
1477be9aa8 Make $generator->send() return the current value
This makes the API easier to use (and is consistent with Python and JS).
2012-05-31 20:03:18 +02:00
Nikita Popov
ee89e228f6 Allow yielding during function calls
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.
2012-05-31 00:00:30 +02:00
Nikita Popov
8790160235 Add auto-increment keys
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.
2012-05-30 05:05:49 +02:00
Nikita Popov
bc08c2cf94 Add support for yielding keys
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.
2012-05-30 02:44:06 +02:00
Nikita Popov
72a91d08e7 Add $generator->close() method
Calling $generator->close() is equivalent to executing a return statement
at the current position in the generator.
2012-05-29 18:11:18 +02:00
Nikita Popov
12e928314f Fix segfault when send()ing to a closed generator 2012-05-29 18:01:08 +02:00
Nikita Popov
3600914ced Add support for $generator->send()
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.
2012-05-29 17:34:33 +02:00
Nikita Popov
4aab08b64c Properly free resources when generator return value not used
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)
2012-05-28 06:43:18 +02:00
Nikita Popov
bcc7d976f3 Set EG(current_execute_data)
This fixes several issues. In particular it makes method generators work
properly and also allows generators using a symbol table.
2012-05-28 06:06:30 +02:00
Nikita Popov
64a643a4e3 Free loop variables
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.
2012-05-27 17:14:20 +02:00
Nikita Popov
247bb737d5 Add support for generator methods 2012-05-27 03:50:31 +02:00
Nikita Popov
cbfa96cad5 Remove wrong dtor call 2012-05-27 00:25:12 +02:00
Nikita Popov
d49d3971e6 Close generator on return 2012-05-26 23:59:22 +02:00
Nikita Popov
5bb3a995c2 Implement return for generators
For generators ZEND_RETURN directly calls ZEND_VM_RETURN(), thus passing
execution back to the caller (zend_generator_resume).

This commit also adds a check that only return; is used in generators and
not return $value;.
2012-05-26 23:07:40 +02:00
Nikita Popov
fafce58683 Add YIELD opcode implementation 2012-05-26 22:44:53 +02:00
Nikita Popov
1a99d1c887 Add way to pass generator object to opcode handlers
The generator zval is put into the return_value_ptr_ptr.
2012-05-26 19:40:29 +02:00
Nikita Popov
f627be5254 Add support for executing a zend_execute_data
This adds another function execute_ex(), which accepts a zend_execute_data
struct to run (contrary to execute(), which accepts a zend_op_array from
which it initialized the execute_data).

This needs a bit more cleanup.
2012-05-26 17:53:13 +02:00
Nikita Popov
2c5ecb4fea Add dummy Iterator implementation
This simply adds dummy rewind/valid/current/key/next methods to Generator.
2012-05-23 16:44:58 +02:00
Nikita Popov
9ce9a7e639 Add initial code for suspending execution
This is just some initial code, which is still quite broken (and needs to be
moved so it can be reused.)
2012-05-23 14:20:25 +02:00
Nikita Popov
40b7533576 Add some boilerplate code for Generator class
The Generator class now uses a zend_generator struct, so it'll be able to
store additional info.

This commit also ensures that Generator cannot be directly instantiated
and extended. The error tests are now in a separate folder from the
(yet-to-come) functional tests.
2012-05-20 14:19:16 +02:00
Nikita Popov
ca59e5464d Add empty Generator class 2012-05-20 00:03:27 +02:00