1
0
mirror of https://github.com/php/php-src.git synced 2026-04-23 07:58:20 +02:00

Merge branch 'PHP-5.6' of https://git.php.net/push/php-src into PHP-5.6

This commit is contained in:
Xinchen Hui
2013-12-15 16:55:29 +08:00
704 changed files with 37330 additions and 27526 deletions
+2 -2
View File
@@ -106,7 +106,7 @@ define dump_bt
printf "%ld", $zvalue->value.lval
end
if $type == 2
printf "%lf", $zvalue->value.dval
printf "%f", $zvalue->value.dval
end
if $type == 3
if $zvalue->value.lval
@@ -185,7 +185,7 @@ define ____printzv_contents
printf "long: %ld", $zvalue->value.lval
end
if $type == 2
printf "double: %lf", $zvalue->value.dval
printf "double: %f", $zvalue->value.dval
end
if $type == 3
printf "bool: "
+4 -1
View File
@@ -259,7 +259,10 @@ The file labelled 'EXPERIMENTAL' should include the following
information::
Any authoring information (known bugs, future directions of the module).
Ongoing status notes which may not be appropriate for SVN comments.
Ongoing status notes which may not be appropriate for Git comments.
In general new features should go to PECL or experimental branches until
there are specific reasons for directly adding it to the core distribution.
Aliases & Legacy Documentation
-----------------------------------
+1 -1
View File
@@ -120,7 +120,7 @@ clean:
distclean: clean
rm -f Makefile config.cache config.log config.status Makefile.objects Makefile.fragments libtool main/php_config.h main/internal_functions_cli.c main/internal_functions.c stamp-h sapi/apache/libphp$(PHP_MAJOR_VERSION).module sapi/apache_hooks/libphp$(PHP_MAJOR_VERSION).module buildmk.stamp Zend/zend_dtrace_gen.h Zend/zend_dtrace_gen.h.bak Zend/zend_config.h TSRM/tsrm_config.h
rm -f php5.spec main/build-defs.h scripts/phpize
rm -f ext/date/lib/timelib_config.h ext/mbstring/oniguruma/config.h ext/mbstring/libmbfl/config.h ext/mysqlnd/php_mysqlnd_config.h
rm -f ext/date/lib/timelib_config.h ext/mbstring/oniguruma/config.h ext/mbstring/libmbfl/config.h ext/oci8/oci8_dtrace_gen.h ext/oci8/oci8_dtrace_gen.h.bak
rm -f scripts/man1/phpize.1 scripts/php-config scripts/man1/php-config.1 sapi/cli/php.1 sapi/cgi/php-cgi.1 ext/phar/phar.1 ext/phar/phar.phar.1
rm -f sapi/fpm/php-fpm.conf sapi/fpm/init.d.php-fpm sapi/fpm/php-fpm.service sapi/fpm/php-fpm.8 sapi/fpm/status.html
rm -f ext/iconv/php_have_bsd_iconv.h ext/iconv/php_have_glibc_iconv.h ext/iconv/php_have_ibm_iconv.h ext/iconv/php_have_iconv.h ext/iconv/php_have_libiconv.h ext/iconv/php_iconv_aliased_libiconv.h ext/iconv/php_iconv_supports_errno.h ext/iconv/php_php_iconv_h_path.h ext/iconv/php_php_iconv_impl.h
+73 -8779
View File
File diff suppressed because it is too large Load Diff
-39
View File
@@ -1,39 +0,0 @@
Between PHP 4.0.6 and 4.1.0, the Zend module struct changed in a way
that broke both source and binary compatibility. If you are
maintaining a third party extension, here's how to update it:
If this was your old module entry:
zend_module_entry foo_module_entry = {
"foo", /* extension name */
foo_functions, /* extension function list */
NULL, /* extension-wide startup function */
NULL, /* extension-wide shutdown function */
PHP_RINIT(foo), /* per-request startup function */
PHP_RSHUTDOWN(foo), /* per-request shutdown function */
PHP_MINFO(foo), /* information function */
STANDARD_MODULE_PROPERTIES
};
Here's how it should look if you want your code to build with PHP
4.1.0 and up:
zend_module_entry foo_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
"foo", /* extension name */
foo_functions, /* extension function list */
NULL, /* extension-wide startup function */
NULL, /* extension-wide shutdown function */
PHP_RINIT(foo), /* per-request startup function */
PHP_RSHUTDOWN(foo), /* per-request shutdown function */
PHP_MINFO(foo), /* information function */
#if ZEND_MODULE_API_NO >= 20010901
PHP_FOO_VERSION, /* extension version number (string) */
#endif
STANDARD_MODULE_PROPERTIES
};
If you don't care about source compatibility with earlier PHP releases
than 4.1.0, you can drop the #if/#endif lines.
-155
View File
@@ -1,155 +0,0 @@
1. strrpos() and strripos() now use the entire string as a needle. Be aware
that the existing scripts may no longer work as you expect.
EX :
<?php
var_dump(strrpos("ABCDEF","DEF"));
var_dump(strrpos("ABCDEF","DAF"));
?>
Will give you different results. The former returns 3 while the latter
returns false rather than the position of the last occurrence of 'D'.
The same applies to strripos().
2. Illegal use of string offsets causes E_ERROR instead of E_WARNING.
EX :
<?php
$a = "foo";
unset($a[0][1][2]);
?>
Fatal error: Cannot use string offset as an array in ... on line 1
3. array_merge() was changed to accept only arrays. If a non-array variable is
passed, a E_WARNING will be thrown for every such parameter. Be careful
because your code may start emitting E_WARNING out of the blue.
4. Be careful when porting from ext/mysql to ext/mysqli. The following
functions return NULL when no more data is available in the result set
(ext/mysql's functions return FALSE).
- mysqli_fetch_row()
- mysqli_fetch_array()
- mysqli_fetch_assoc()
5. PATH_TRANSLATED server variable is no longer set implicitly under
Apache2 SAPI in contrast to the situation in PHP 4, where it is set to the
same value as the SCRIPT_FILENAME server variable when it is not populated
by Apache. This change was made to comply with the CGI specification.
Please refer to bug #23610 for further information.
6. Starting PHP 5.0.0 the T_ML_CONSTANT constant is no longer defined by the
ext/tokenizer extension. If error_reporting is set to E_ALL notices will
be produced. Instead of T_ML_CONSTANT for /* */ the T_COMMENT constant
is used, thus both // and /* */ are resolved as the T_COMMENT constant.
However the PHPDoc style comments /** */ ,which starting PHP 5 are parsed
by PHP, are recongnized as T_DOC_COMMENT.
7. $_SERVER should be populated with argc and argv if variables_order
includes "S". If you have specifically configured your system to not
create $_SERVER, then of course it shouldn't be there. The change was to
always make argc and argv available in the CLI version regardless of the
variables_order setting. As in, the CLI version will now always populate
the global $argc and $argv variables.
8. In some cases classes must be declared before used. It only happens only
if some of the new features of PHP 5 are used. Otherwise the behaviour is
the old.
Example 1 (works with no errors):
<?php
$a = new a();
class a {
}
?>
Example 2 (throws an error):
<?php
$a = new a();
interface b{
}
class a implements b {
}
?>
Output (example 2) :
Fatal error: Class 'a' not found in /tmp/cl.php on line 2
9. get_class() starting PHP 5 returns the name of the class as it was
declared which may lead to problems in older scripts that rely on
the previous behaviour - the class name is lowercased. Expect the
same behaviour from get_parent_class() when applicable.
Example :
<?php
class FooBar {
}
class ExtFooBar extends FooBar{}
$a = new FooBar();
var_dump(get_class($a), get_parent_class($a));
?>
Output (PHP 4):
string(6) "foobar"
string(9) "extfoobar"
Output (PHP 5):
string(6) "FooBar"
string(9) "ExtFooBar"
----------------------------------------------------------------------
Example code that will break :
//....
function someMethod($p) {
if (get_class($p) != 'helpingclass') {
return FALSE;
}
//...
}
//...
Possible solution is to search for get_class() and get_parent_class() in
all your scripts and use strtolower().
10. get_class_methods() returns the names of the methods of a class as they
declared. In PHP4 the names are all lowercased.
Example code :
<?php
class Foo{
function doFoo(){}
function hasFoo(){}
}
var_dump(get_class_methods("Foo"));
?>
Output (PHP4):
array(2) {
[0]=>
string(5) "dofoo"
[1]=>
string(6) "hasfoo"
}
Output (PHP5):
array(2) {
[0]=>
string(5) "doFoo"
[1]=>
string(6) "hasFoo"
}
11. Assignment $this is impossible. Starting PHP 5.0.0 $this has special
meaning in class methods and is recognized by the PHP parser. The latter
will generate a parse error when assignment to $this is found
Example code :
<?php
class Foo {
function assignNew($obj) {
$this = $obj;
}
}
$a = new Foo();
$b = new Foo();
$a->assignNew($b);
echo "I was executed\n";
?>
Output (PHP 4):
I was executed
Output (PHP 5):
PHP Fatal error: Cannot re-assign $this in /tmp/this_ex.php on line 4
+1 -1
View File
@@ -46,7 +46,7 @@ Opening Streams
===============
In most cases, you should use this API:
PHPAPI php_stream *php_stream_open_wrapper(char *path, char *mode,
PHPAPI php_stream *php_stream_open_wrapper(const char *path, const char *mode,
int options, char **opened_path TSRMLS_DC);
Where:
+14 -14
View File
@@ -5,7 +5,7 @@ This document describes how to submit an enhancement or patch for PHP.
It's easy!
You don't need any login accounts or special access to download,
build, debug and begin submitting PHP, PECL or PEAR code, tests or
build, debug and begin submitting PHP or PECL code, tests or
documentation. Once you've followed this README and had several
patches accepted, commit privileges are often quickly granted.
@@ -16,8 +16,8 @@ http://phpadvent.org/2008/less-whining-more-coding-by-elizabeth-smith
Online Forums
-------------
There are several IRC channels where PHP developers are often
available to discuss questions. They include #php.pecl, #php.doc and
#pear on the EFNet network and #php-dev-win on FreeNode.
available to discuss questions. They include #php.pecl and #php.doc
on the EFNet network and #php-dev-win on FreeNode.
PHP Patches
@@ -78,7 +78,7 @@ of type 'text/*' are accepted.
PECL Extension Patches: http://pecl.php.net/
--------------------------------------------
If you are fixing broken functionality in a PECL extension then create
a bug or identify an existing bug at http://pecl.php.net/bugs/. A bug
a bug or identify an existing bug at http://bugs.php.net/. A bug
can be used to track the patch progress and prevent your changes
getting lost in the PHP mail archives.
@@ -114,15 +114,15 @@ http://pear.php.net/manual/en/guide-developers.php
How to create your PHP, PHP Documentation or PECL patch
-------------------------------------------------------
PHP and PECL use Subversion (SVN) for revision control. Read
http://www.php.net/svn.php for help on using SVN to get and build PHP
source code. We recommend using a Sparse Directory checkout described
in http://wiki.php.net/vcs/svnfaq. If you are new to SVN, read
http://svnbook.red-bean.com.
PHP and most PECL packages use Git for revision control. Some PECL
packages use Subversion (SVN) Read http://www.php.net/git.php for help
on using Git to get and build PHP source code. We recommend to look
at our workflow on https://wiki.php.net/vcs/gitworkflow and our FAQ
https://wiki.php.net/vcs/gitfaq.
Generally we ask that bug fix patches work on the current stable PHP
development branches and on "trunk". New PHP features only need to
work on "trunk".
development branches and on "master". New PHP features only need to
work on "master".
Read CODING_STANDARDS before you start working.
@@ -134,7 +134,7 @@ comprehensive.
After testing is finished, create a patch file using the command:
svn diff > your_patch.txt
git diff > your_patch.txt
For ease of review and later troubleshooting, submit individual
patches for each bug or feature.
@@ -142,7 +142,7 @@ patches for each bug or feature.
Checklist for submitting your PHP or PECL code patch
----------------------------------------------------
- Update SVN source just before running your final 'diff' and
- Update git source just before running your final 'diff' and
before testing.
- Add in-line comments and/or have external documentation ready.
Use only "/* */" style comments, not "//".
@@ -175,7 +175,7 @@ about these questions:
What happens when your PHP or PECL patch is applied
---------------------------------------------------
Your name will likely be included in the SVN commit log. If your
Your name will likely be included in the Git commit log. If your
patch affects end users, a brief description and your name might be
added to the NEWS file.
+1 -1
View File
@@ -1,6 +1,6 @@
## process this file with automake to produce Makefile.am
AUTOMAKE_OPTIONS=foreign
noinst_LTLIBRARIES=libtsrm.la
libtsrm_la_SOURCES = TSRM.c tsrm_strtok_r.c tsrm_virtual_cwd.c
libtsrm_la_SOURCES = TSRM.c tsrm_strtok_r.c
depend:
-4
View File
@@ -143,10 +143,6 @@ SOURCE=.\tsrm_strtok_r.c
# End Source File
# Begin Source File
SOURCE=.\tsrm_virtual_cwd.c
# End Source File
# Begin Source File
SOURCE=.\tsrm_win32.c
# End Source File
# End Group
+1 -1
View File
@@ -1,5 +1,5 @@
// vim:ft=javascript
// $Id$
ADD_SOURCES("TSRM", "TSRM.c tsrm_strtok_r.c tsrm_virtual_cwd.c tsrm_win32.c");
ADD_SOURCES("TSRM", "TSRM.c tsrm_strtok_r.c tsrm_win32.c");
+1 -1
View File
@@ -32,7 +32,7 @@
#ifdef TSRM_WIN32
#include <Sddl.h>
#include "tsrm_win32.h"
#include "tsrm_virtual_cwd.h"
#include "zend_virtual_cwd.h"
#ifdef ZTS
static ts_rsrc_id win32_globals_id;
+85 -408
View File
@@ -1,486 +1,163 @@
$Id$
PHP 5.5 UPGRADE NOTES
PHP X.Y UPGRADE NOTES
1. Backward Incompatible Changes
2. New Features
2. Changes in SAPI modules
3. Deprecated Functionality
4. Changed Functions
5. New Functions
6. New Classes and Interfaces
7. Removed Extensions
8. Other Changes to Extensions
9. New Global Constants
1. Backward Incompatible Changes
2. New Features
2. Changes in SAPI modules
3. Deprecated Functionality
4. Changed Functions
5. New Functions
6. New Classes and Interfaces
7. Removed Extensions
8. Other Changes to Extensions
9. New Global Constants
10. Changes to INI File Handling
11. Windows Support
12. Other Changes
11. Other Changes
========================================
1. Backward Incompatible Changes
========================================
- Dropped Windows XP and 2003 support. (Pierre)
- Core:
Removed $HTTP_RAW_POST_DATA global variable. Restore backwards compatibility
by:
<?php
global $HTTP_RAW_POST_DATA;
if (!isset($HTTP_RAW_POST_DATA)) {
$HTTP_RAW_POST_DATA = file_get_contents("php://input");
}
?>
- All internal case insensitivity handling for class, function and constant
names is done according to ASCII rules. Current locale settings are ignored.
- self, parent & static keywords now are always case-insensitive (see bug
#60833).
- Removed Logo GUIDs: php_logo_guid(), php_egg_logo_guid(),
php_real_logo_guid() and zend_logo_guid()
- JSON:
json_decode() no longer accepts non-lowercase variants of lone JSON true,
false or null values. For example, True or FALSE will now cause json_decode to
return NULL and set an error value you can fetch with json_last_error().
This affects JSON texts consisting solely of true, false or null. Text
containing non-lowercase values inside JSON arrays or objects has never been
accepted.
========================================
2. New Features
========================================
- Support list in foreach. (Laruence)
(http://php.net/foreach#control-structures.foreach.list,
http://wiki.php.net/rfc/foreachlist)
- Added constant scalar expressions syntax
(https://wiki.php.net/rfc/const_scalar_exprs)
- Support "finally" keyword. (Laruence)
(http://php.net/exceptions, http://wiki.php.net/rfc/finally)
- Added dedicated syntax for variadic functions.
(https://wiki.php.net/rfc/variadics)
- Support constant array/string dereferencing. (Laruence)
(http://php.net/manual/en/language.types.array.php,
https://wiki.php.net/rfc/constdereference)
- The php://input stream is now re-usable and can be used concurrently with
enable_post_data_reading=0.
- Add support for using empty() on the result of function calls and
other expressions. Thus it is now possible to write empty(getArray()),
for example. (http://php.net/manual/en/function.empty.php,
https://wiki.php.net/rfc/empty_isset_exprs)
- Added gost-crypto (CryptoPro S-box) hash algo.
- Added generators.
(http://php.net/generators, https://wiki.php.net/rfc/generators)
- Added openssl certificate fingerprint support (inclusive stream context
option).
- ClassName::class syntax returning full class name for a class as a
string constant. (http://php.net/oop5.basic,
https://wiki.php.net/rfc/class_name_scalars)
- Added support for non-scalar Iterator keys in foreach.
(http://php.net/manual/en/control-structures.foreach.php,
https://wiki.php.net/rfc/foreach-non-scalar-keys).
- Bundled Zend OPcache extension to improve performance
(http://php.net/manual/en/book.opcache.php,
https://wiki.php.net/rfc/optimizerplus)
- Added a simplified password hashing API
(http://php.net/password, https://wiki.php.net/rfc/password_hash)
- Added openssl crypto method stream context option.
========================================
2. Changes in SAPI modules
========================================
- Support for changing the process's title in CLI/CLI-Server
SAPIs. (Keyur)
(http://php.net/manual/en/function.cli-set-process-title.php,
http://php.net/manual/en/function.cli-get-process-title.php,
https://wiki.php.net/rfc/cli_process_title)
- Support for systemd in php-fpm: Add --with-fpm-systemd option to
report health to systemd, and add systemd_interval option to
configure this. The service can now use Type=notify in the systemd
unit file. (Remi)
========================================
3. Deprecated Functionality
========================================
- The original MySQL extension is now deprecated and will generate
deprecation warnings when connecting to a database through
mysql_connect(), mysql_pconnect() or by establishing an implicit
connection. Use MySQLi or PDO instead.
- The preg_replace /e modifier is now deprecated. Use
preg_replace_callback instead.
(https://wiki.php.net/rfc/remove_preg_replace_eval_modifier)
- IntlDateFormatter::setTimeZoneID() and datefmt_set_timezone_id() are
deprecated. Use IntlDateFormatter::setTimeZone() or
datefmt_set_timezone() instead.
- mcrypt_ecb(), mcrypt_cbc(), mcrypt_cfb() and mcrypt_ofb() now throw
E_DEPRECATED. Their use was already previously discouraged in the
documentation, but that predated the existence of E_DEPRECATED.
- Incompatible context calls:
Instance calls from an incompatible context are now deprecated and issue
E_DEPRECATED instead of E_STRICT. See https://wiki.php.net/rfc/incompat_ctx
========================================
4. Changed Functions
========================================
- pack()/unpack() had the following changes, which bring it more in
line with Perl's behavior: - Implemented format character "Z": NULL
padded string, with trailing NULL bytes removed. - Changed format
character "a": this no longer removes trailing NULL bytes. -
Changed format character "A": all trailing ASCII whitespace is now
removed (defined as spaces, tabs, \r, \n and NULL).
- cURL:
CURLOPT_SAFE_UPLOAD is now turned on by default and uploads with @file
do not work unless it is explicitly set to false.
- MessageFormatter::format() and related functions now accepted named
arguments and mixed numeric/named arguments in ICU 4.8+.
- Crypt:
crypt() will now raise an E_NOTICE error if the salt parameter is omitted.
See: https://wiki.php.net/rfc/crypt_function_salt
- MessageFormatter::format() and related functions now don't error out
when an insufficient argument count is provided. Instead, the
placeholders will remain unsubstituted.
- MessageFormatter::parse() and MessageFormat::format() (and their
static equivalents) now don't throw away better than second
precision in the arguments.
- IntlDateFormatter::__construct and datefmt_create() now accept for
the $timezone argument time zone identifiers, IntlTimeZone objects,
DateTimeZone objects and NULL. It used to accept only time zone
identifiers and NULL. Invalid time zone identifiers are no longer
accepted. Empty strings are no longer accepted.
- The default time zone used in IntlDateFormatter::__construct and
datefmt_create() (when the corresponding argument is not passed or
NULL is passed) is now the one given by date_default_timezone_get(),
not the default ICU time zone.
- The time zone passed to the IntlDateFormatter is ignored if it is
NULL and if the calendar passed is an IntlCalendar object -- in this
case, the IntlCalendar's time zone will be used instead. Otherwise,
the time zone specified in the $timezone argument is used
instead. This does not affect old code, as IntlCalendar was
introduced in this version.
- IntlDateFormatter::__construct and datefmt_create() now accept for
the $calendar argument also IntlCalendar objects.
- IntlDateFormatter::getCalendar() and datefmt_get_calendar() return
false if the IntlDateFormatter was set up with an IntlCalendar
instead of the constants
IntlDateFormatter::GREGORIAN/TRADITIONAL. IntlCalendar did not exist
before this version.
- IntlDateFormatter::setCalendar() and datefmt_set_calendar() now also
accept an IntlCalendar object, in which case its time zone is
taken. Passing a constant is still allowed, and still keeps the time
zone.
- IntlDateFormatter::format() and datefmt_format() now also accept an
IntlCalendar object for formatting.
- set_error_handler(NULL) can now be used to reset the error handler.
Furthermore both set_error_handler(NULL) and
set_exception_handler(NULL) will now return the previously defined
error/exception handler. Previously bool(true) was returned.
- setcookie(), setrawcookie() and ext/session now send Max-Age headers
alongside Expires headers. (see
https://wiki.php.net/rfc/cookie_max-age)
- curl_setopt now accepts new option CURLOPT_SAFE_UPLOAD and CURLFile
object for safer file uploads (see
https://wiki.php.net/rfc/curl-file-upload)
- Functions in the socket extension now do not emit warnings when the
errno is EAGAIN, EWOULDBLOCK or EINPROGRESS.
- Since 5.5.2, spl_autoload_functions() returns different names for
different lambda functions registered via spl_autoload_register().
- Since 5.5.3, DOMDocument::schemaValidateSource() and
DOMDocument::schemaValidate() accept flag parameter. Only flag
available now is LIBXML_SCHEMA_CREATE. Default is 0.
- Since 5.5.4, fputcsv() has fifth parameter escape_char, allowing to
specify escape char.
- XMLReader:
XMLReader::getAttributeNs and XMLReader::getAttributeNo now return NULL if
the attribute could not be found, just like XMLReader::getAttribute.
========================================
5. New Functions
========================================
- Core:
- array_column()
- boolval()
- password_get_info()
- password_hash()
- password_needs_rehash()
- password_verify()
- GMP:
Added gmp_root($a, $nth) and gmp_rootrem($a, $nth) for calculating nth roots.
- cURL:
- curl_file_create
- Openssl:
Added string openssl_x509_fingerprint($x509, $type, $binary).
- GD
- imageflip
- imagecrop
- imagecropauto
- imagesetinterpolation
- imageaffine
- imageaffinematrixget
- imageaffinematrixconcat
- imagescale
- LDAP:
Added ldap_escape($value, $ignore = "", $flags = 0).
- Hash:
- hash_pbkdf2()
- Intl:
- datefmt_format_object()
- datefmt_get_calendar_object()
- datefmt_get_timezone()
- datefmt_set_timezone()
- datefmt_get_calendar_object()
- intlcal_create_instance()
- intlcal_get_keyword_values_for_locale()
- intlcal_get_now()
- intlcal_get_available_locales()
- intlcal_get()
- intlcal_get_time()
- intlcal_set_time()
- intlcal_add()
- intlcal_set_time_zone()
- intlcal_after()
- intlcal_before()
- intlcal_set()
- intlcal_roll()
- intlcal_clear()
- intlcal_field_difference()
- intlcal_get_actual_maximum()
- intlcal_get_actual_minimum()
- intlcal_get_day_of_week_type()
- intlcal_get_first_day_of_week()
- intlcal_get_greatest_minimum()
- intlcal_get_least_maximum()
- intlcal_get_locale()
- intlcal_get_maximum()
- intlcal_get_minimal_days_in_first_week()
- intlcal_get_minimum()
- intlcal_get_time_zone()
- intlcal_get_type()
- intlcal_get_weekend_transition()
- intlcal_in_daylight_time()
- intlcal_is_equivalent_to()
- intlcal_is_lenient()
- intlcal_is_set()
- intlcal_is_weekend()
- intlcal_set_first_day_of_week()
- intlcal_set_lenient()
- intlcal_equals()
- intlcal_get_repeated_wall_time_option()
- intlcal_get_skipped_wall_time_option()
- intlcal_set_repeated_wall_time_option()
- intlcal_set_skipped_wall_time_option()
- intlcal_from_date_time()
- intlcal_to_date_time()
- intlcal_get_error_code()
- intlcal_get_error_message()
- intlgregcal_create_instance()
- intlgregcal_set_gregorian_change()
- intlgregcal_get_gregorian_change()
- intlgregcal_is_leap_year()
- intltz_create_time_zone()
- intltz_create_default()
- intltz_get_id()
- intltz_get_gmt()
- intltz_get_unknown()
- intltz_create_enumeration()
- intltz_count_equivalent_ids()
- intltz_create_time_zone_id_enumeration()
- intltz_get_canonical_id()
- intltz_get_region()
- intltz_get_tz_data_version()
- intltz_get_equivalent_id()
- intltz_use_daylight_time()
- intltz_get_offset()
- intltz_get_raw_offset()
- intltz_has_same_rules()
- intltz_get_display_name()
- intltz_get_dst_savings()
- intltz_from_date_time_zone()
- intltz_to_date_time_zone()
- intltz_get_error_code()
- intltz_get_error_message()
- IntlDateFormatter::formatObject()
- IntlDateFormatter::getCalendarObject()
- IntlDateFormatter::getTimeZone()
- IntlDateFormatter::setTimeZone()
- Sockets:
- socket_sendmsg()
- socket_recvmsg()
- socket_cmsg_space()
- SPL:
- SplFixedArray::__wakeup()
- SplDoublyLinkedList::add()
- RecursiveTreeIterator::getPostfix() (5.5.2)
- RecursiveTreeIterator::setPostfix() (5.5.2)
- Zend OPcache:
- opcache_get_configuration()
- opcache_get_status()
- opcache_reset()
- Zip:
Added ZipArchive::setPassword($password)
========================================
6. New Classes and Interfaces
========================================
- Intl:
- IntlCalendar
- IntlGregorianCalendar
- IntlTimeZone
- IntlBreakIterator
- IntlRuleBasedBreakIterator
- IntlCodePointBreakIterator
- UConverter
- cURL:
- CURLFile
========================================
7. Removed Extensions
========================================
None
========================================
8. Other Changes to Extensions
========================================
- Intl:
- This extension now requires ICU 4.0+.
- Phar:
- Added ability of resolving alias created by Phar::map
- GMP:
The GMP extension now uses objects as the underlying data structure, rather
than resources. GMP instances now support dumping, serialization, cloning,
casts to primitive types and have overloaded operators.
(RFC: https://wiki.php.net/rfc/operator_overloading_gmp)
- OCI8:
- Added Implicit Result Set support for Oracle Database 12c with a
new oci_get_implicit_resultset() function.
- Using 'oci_execute($s, OCI_NO_AUTO_COMMIT)' for a SELECT no longer
unnecessarily initiates an internal ROLLBACK during connection
close.
- Added DTrace probes enabled with PHP's generic --enable-dtrace
- The oci_internal_debug() function is now a no-op.
- The phpinfo() output format for OCI8 has changed.
========================================
9. New Global Constants
========================================
- mysqli:
- Added MYSQLI_SERVER_PUBLIC_KEY constant to be used with mysqli_options()
- cURL:
- Added CURLOPT_SAFE_UPLOAD to be used with curl_setopt().
- Added CURL_WRAPPERS_ENABLED to reflect --with-curlwrappers.
- GD
- Added constants for imageflip:
. IMG_FLIP_HORIZONTAL
. IMG_FLIP_VERTICAL
. IMG_FLIP_BOTH
- Added constants for imagecrop
. IMG_CROP_DEFAULT
. IMG_CROP_TRANSPARENT
. IMG_CROP_BLACK
. IMG_CROP_WHITE
. IMG_CROP_SIDES
. IMG_CROP_THRESHOLD
- Added constants for imagesetinterpolation, used by imagescale
imagerotate and imageaffine:
. IMG_BELL
. IMG_BESSEL
. IMG_BILINEAR_FIXED
. IMG_BICUBIC
. IMG_BICUBIC_FIXED
. IMG_BLACKMAN
. IMG_BOX
. IMG_BSPLINE
. IMG_CATMULLROM
. IMG_GAUSSIAN
. IMG_GENERALIZED_CUBIC
. IMG_HERMITE
. IMG_HAMMING
. IMG_HANNING
. IMG_MITCHELL
. IMG_POWER
. IMG_QUADRATIC
. IMG_SINC
. IMG_NEAREST_NEIGHBOUR
. IMG_WEIGHTED4
. IMG_TRIANGLE
- Added constants for imageaffinematrixget
. IMG_AFFINE_TRANSLATE
. IMG_AFFINE_SCALE
. IMG_AFFINE_ROTATE
. IMG_AFFINE_SHEAR_HORIZONTAL
. IMG_AFFINE_SHEAR_VERTICAL
- LDAP:
LDAP_ESCAPE_FILTER int(1)
LDAP_ESCAPE_DN int(2)
========================================
10. Changes to INI File Handling
========================================
- Core:
- Added sys_temp_dir INI directive, for specifying temporary
directory.
- Intl:
- Added intl.use_exceptions INI directive, which controls what
happens when global errors are set together with intl.error_level.
- MSSQL:
- mssql.compatability_mode renamed to mssql.compatibility_mode in 5.5.2,
old directive still supported for BC reasons.
- mysqlnd:
- Added mysqlnd.sha256_server_public_key INI PERDIR setting that
affects all APIs which use(are built) for mysqlnd. This allows
ext/mysqli to be used with the new auth protocol, although at
coarser level.
- Sessions:
- Added session.use_strict_mode in 5.5.3, which prevents session
fixation attacks and session collisions.
See also https://wiki.php.net/rfc/strict_sessions
- Zend OPcache (See http://php.net/manual/en/book.opcache.php)
- Added the following directives:
- opcache.enable (default "1")
- opcache.memory_consumption (default "64")
- opcache.interned_strings_buffer (default "4")
- opcache.max_accelerated_files (default "2000")
- opcache.max_wasted_percentage (default "5")
- opcache.use_cwd (default "1")
- opcache.validate_timestamps (default "1")
- opcache.revalidate_freq (default "2")
- opcache.revalidate_path (default "0")
- opcache.save_comments (default "1")
- opcache.load_comments (default "1")
- opcache.fast_shutdown (default "0")
- opcache.enable_file_override (default "0")
- opcache.optimization_level (default "0xffffffff")
- opcache.inherited_hack (default "1")
- opcache.blacklist_filename (default "")
- opcache.max_file_size (default "0")
- opcache.consistency_checks (default "0")
- opcache.force_restart_timeout (default "180")
- opcache.error_log (default "" which means stderr)
- opcache.log_verbosity_level (default "1")
- opcache.preferred_memory_model (default "")
- opcache.protect_memory (default "0")
- opcache.mmap_base (Windows-only)
Removed always_populate_raw_post_data.
========================================
11. Windows Support
11. Other Changes
========================================
- The Apache 2.4 handler is supported as of PHP 5.5.0
- File upload:
Uploads equal or greater than 2GB in size are now accepted.
- OPcache: Errors like 'unable to reattach to base address' could
happen in many common setups. It is due to some technical and
design restriction in the engine and could not be fixed easily
before 5.5.0 was released.
- HTTP stream wrapper:
HTTP 1.1 requests now include a Connection: close header unless explicitly
overridden by setting a Connection header via the header context option.
A possible fix is to tweak the opcache.mmap_base INI setting by
forcing the first address to be tried.
For x86 version, the following addreses can be tried:
. 0x20000000, 0x21000000, 0x30000000, 0x31000000, 0x50000000
and for x64 (still experimental):
. 0x0000100000000000, 0x0000200000000000, 0x0000300000000000, 0x0000700000000000
========================================
12. Other Changes
========================================
- If the APC or WinCache user cache APIs were used before, consider
these alternatives for PHP 5.5:
- APCu
- all supported OSes: http://pecl.php.net/package/APCu
- Windows: http://windows.php.net/downloads/pecl/releases/apcu/
- WinCache, Windows only: http://pecl.php.net/package/WinCache
- Zip:
New --with-libzip option allow to use system libzip. Version > 0.11 required.
+82 -78
View File
@@ -3,11 +3,10 @@ $Id$
UPGRADE NOTES - PHP X.Y
1. Internal API changes
a. Executor changes
b. Streams pooling API
c. Lowercasing and locales
d. zend_qsort_r
e. get_current_key
a. Addition of do_operation and compare object handlers
b. return_value_ptr now always available, RETVAL_ZVAL_FAST macros
c. POST data handling
d. Arginfo changes
2. Build system changes
a. Unix build system changes
@@ -18,103 +17,108 @@ UPGRADE NOTES - PHP X.Y
1. Internal API changes
========================
a. Executor changes
a. Addition of do_operation and compare object handlers
* extensions can't override zend_execute() any more, they should override
zend_execute_ex() instead. The EG(current_execute_data) is already
initialized in zend_execute_ex(), so for compatibility extensions
may need to use EG(current_execute_data)->prev_execute_data instead.
* removed EG(arg_types_stack), EX(fbc), EX(called_scope), EX(current_object)
* added op_array->nested_calls. It's calculated at compile time.
* added EX(call_slots). It is an array to store information about syntaticaly
nested calls (e.g. foo(bar())). It's preallocated together with execute_data.
* added EX(call) - pointer to a current calling function. Actually an
element of EX(call_slots)
* opcodes INIT_METHOD_CALL, ZEND_INIT_STATIC_METHOD_CALL,
ZEND_INIT_FCALL_BY_NAME, ZEND_INIT_NS_FCALL_BY_NAME use result.num as
an index in EX(call_slots)
* opcode ZEND_NEW uses extended_vallue as an index in EX(call_slots)
* opcoes ZEND_DO_FCALL and ZEND_DO_FCALL_BY_NAME use op2.num as
an index in EX(call_slots)
* added op_array->used_stack. It's calculated at compile time and the
corresponding stack space is preallocated together with execute_data.
ZEND_SEND* and ZEND_DO_FCALL* don't need to check for stack overflow
anymore.
* Removed execute_data->Ts field. The VM temporary variables always allocated
immediately before execute_data structure. Now they are accessed by offset
from the execute_data base pointer (instead of execute_data->Ts). Compiler
stores new offsets in op_array->opcodes[*].op?.num. You can use macros
EX_TMP_VAR() and EX_TMP_VAR_NUM() to access temp_variable by offset or
number. You can convert number to offset using EX_TMP_VAR_NUM(0, num) or
offset to number (EX_TMP_VAR_NUM(0,0)-EX_TMP_VAR(0,offset)).
* Removed execute_data->CVs field. The VM compiled variables always allocated
immediately after execute_data structure. Now they are accessed by offset
from the execute_data base pointer (instead of execute_data->CVs). You can
use macros EX_CV_NUM() to access compiled variables by number.
Two new object handlers have been added:
b. Streams pooling API
do_operation:
typedef int (*zend_object_do_operation_t)(
zend_uchar opcode, zval *result, zval *op1, zval *op2 TSRMLS_DC
);
The streams pooling API has been removed. The following functions no longer
exist:
compare:
typedef int (*zend_object_compare_zvals_t)(
zval *result, zval *op1, zval *op2 TSRMLS_DC
);
PHPAPI int php_stream_context_get_link(php_stream_context *context,
const char *hostent, php_stream **stream);
PHPAPI int php_stream_context_set_link(php_stream_context *context,
const char *hostent, php_stream *stream);
PHPAPI int php_stream_context_del_link(php_stream_context *context,
php_stream *stream);
The first handler is used to overload arithmetic operations. The first
argument specifies the opcode of the operator, result is the target zval,
op1 the first operand and op2 the second operand. For unary operations
op2 is NULL. If the handler returns FAILURE PHP falls back to the default
behavior for the operation.
c. Lowercasing and locales
The second handler is used to perform comparison operations with
non-objects. The value written into result must be an IS_LONG with value
-1 (smaller), 0 (equal) or 1 (greater). The return value is a SUCCESS/FAILURE
return code. The difference between this handler and compare_objects is
that it will be triggered for comparisons with non-objects and objects of
different types. It takes precedence over compare_objects.
The lowercasing functions in zend_operators.c were split into those that do
lowercasing according to locale rules and those that do ASCII lowercasing.
ASCII:
Further docs in the RFC: https://wiki.php.net/rfc/operator_overloading_gmp
zend_str_tolower_copy
zend_str_tolower_dup
zend_str_tolower
zend_binary_strcasecmp
zend_binary_strncasecmp
b. return_value_ptr now always available, RETVAL_ZVAL_FAST macros
Locale-based:
zend_binary_strncasecmp_l
zend_binary_strcasecmp_l
zend_binary_zval_strcasecmp
zend_binary_zval_strncasecmp
string_compare_function_ex
string_case_compare_function
The return_value_ptr argument to internal functions is now always set.
Previously it was only available for functions returning by-reference.
return_value_ptr can now be used to return zvals without copying them.
For this purpose two new macros are provided:
Internal engine lowercasing will be using ASCII-only rules. User-facing functions,
such as strcasecmp, will be using locale rules.
RETVAL_ZVAL_FAST(zv); /* analog to RETVAL_ZVAL(zv, 1, 0) */
RETURN_ZVAL_FAST(zv); /* analog to RETURN_ZVAL(zv, 1, 0) */
Two new functions - zend_binary_strncasecmp_l and zend_binary_strcasecmp_l - added as
locale-based counterparts to zend_binary_strcasecmp and zend_binary_strncasecmp.
The macros behave similarly to the non-FAST variants with copy=1 and
dtor=0, but will try to return the zval without making a copy by utilizing
return_value_ptr.
c. POST data handling
The sapi_request_info's members post_data, post_data_len and raw_post_data as
well as raw_post_data_len have been replaced with a temp PHP stream
request_body.
The recommended way to access raw POST data is to open and use a php://input
stream wrapper. It is safe to be used concurrently and more than once.
d. zend_qsort_r
d. Arginfo changes
Added the function zend_qsort_r():
The pass_rest_by_reference argument of the ZEND_BEGIN_ARG_INFO and
ZEND_BEGIN_ARG_INFO_EX() is no longer used. The value passed to it is ignored.
typedef int (*compare_r_func_t)(const void *, const void * TSRMLS_DC, void *);
void zend_qsort_r(void *base, size_t nmemb, size_t siz, compare_r_func_t compare, void *arg TSRMLS_DC);
Instead a variadic argument is created using ZEND_ARG_VARIADIC_INFO():
The extra argument it has (relatively to zend_qsort()) is passed to the
comparison function.
ZEND_ARG_VARIADIC_INFO(0, name) /* pass rest by value */
ZEND_ARG_VARIADIC_INFO(1, name) /* pass rest by reference */
ZEND_ARG_VARIADIC_INFO(ZEND_SEND_PREFER_REF, name)
/* pass rest by prefer-ref */
e. get_current_key
ZEND_ARG_VARIADIC_INFO() should only be used for the last argument.
The signature of the get_current_key iteration handler has been changed to:
The following changes were applied to the zend_arg_info struct:
void (*get_current_key)(zend_object_iterator *iter, zval *key TSRMLS_DC);
typedef struct _zend_arg_info {
const char *class_name;
zend_uint class_name_len;
zend_uchar type_hint;
+ zend_uchar pass_by_reference;
zend_bool allow_null;
- zend_bool pass_by_reference;
+ zend_bool is_variadic;
} zend_arg_info;
The key should be written into the zval* using the ZVAL_* macros.
The following changes were applied to the zend_internal_function_info struct:
typedef struct _zend_internal_function_info {
zend_uint required_num_args;
zend_uchar _type_hint;
zend_bool return_reference;
- zend_bool pass_rest_by_reference;
+ zend_bool _allow_null;
+ zend_bool _is_variadic;
} zend_internal_function_info;
The CHECK_ARG_SEND_TYPE(), ARG_MUST_BE_SENT_BY_REF(),
ARG_SHOULD_BE_SENT_BY_REF() and ARG_MAY_BE_SENT_BY_REF() macros now assume
that the argument passed to them is a zend_function* and that it is non-NULL.
========================
2. Build system changes
========================
a. Unix build system changes
-
- The bison version check is now a blacklist instead of a whitelist.
- The bison binary can be specified through the YACC environment/configure
variable. Previously `bison` was assumed to be in $PATH.
b. Windows build system changes
- Drop Windows XP and 2003 support.
-
+1 -1
View File
@@ -18,7 +18,7 @@ libZend_la_SOURCES=\
zend_default_classes.c \
zend_iterators.c zend_interfaces.c zend_exceptions.c \
zend_strtod.c zend_closures.c zend_float.c zend_string.c zend_signal.c \
zend_generators.c
zend_generators.c zend_virtual_cwd.c zend_ast.c
libZend_la_LDFLAGS =
libZend_la_LIBADD = @ZEND_EXTRA_LIBS@
+3 -3
View File
@@ -9,11 +9,11 @@ Modified: 2001-09-17
1. Background/Need
==================
Many internal function of PHP will reject parameters because of their
Many internal functions of PHP will reject parameters because of their
type (the array and variable function come to mind). For userland
this is not an easy task as there is no uniform way to do it. An
addition to the engine for requiring loose types would allow
delevopers to know that the data passed to their functions is of the
developers to know that the data passed to their functions are of the
correct type and reduce the need for duplicating the same code in
every function to check for the type of data.
@@ -57,7 +57,7 @@ function foo (array $var){
===========
Mis-matches in type should be reported as fatal errors and should halt
the execution of a script as that function can not be run and code
the execution of a script as that function cannot be run and code
following could not reliably run.
+8
View File
@@ -119,6 +119,10 @@ SOURCE=.\zend_API.c
# End Source File
# Begin Source File
SOURCE=.\zend_ast.c
# End Source File
# Begin Source File
SOURCE=.\zend_builtin_functions.c
# End Source File
# Begin Source File
@@ -429,6 +433,10 @@ SOURCE=.\zend_ts_hash.h
SOURCE=.\zend_variables.h
# End Source File
# Begin Source File
SOURCE=.\zend_virtual_cwd.c
# End Source File
# End Group
# Begin Group "Parsers"
+4
View File
@@ -140,6 +140,10 @@ SOURCE=.\zend_alloc.c
# End Source File
# Begin Source File
SOURCE=.\zend_ast.c
# End Source File
# Begin Source File
SOURCE=.\zend_API.c
# End Source File
# Begin Source File
+18 -9
View File
@@ -3,8 +3,13 @@ dnl
dnl This file contains local autoconf functions.
AC_DEFUN([LIBZEND_BISON_CHECK],[
# we only support certain bison versions
bison_version_list="2.4 2.4.1 2.4.2 2.4.3 2.5 2.5.1 2.6 2.6.1 2.6.2 2.6.3 2.6.4 2.6.5 2.7"
# we only support certain bison versions;
# min: 2.4 (i.e. 204, major * 100 + minor for easier comparison)
bison_version_min="204"
# non-working versions, e.g. "3.0 3.2";
# remove "none" when introducing the first incompatible bison version an
# separate any following additions by spaces
bison_version_exclude="3.0"
# for standalone build of Zend Engine
test -z "$SED" && SED=sed
@@ -17,18 +22,22 @@ AC_DEFUN([LIBZEND_BISON_CHECK],[
if test -n "$bison_version_vars"; then
set $bison_version_vars
bison_version="${1}.${2}"
for bison_check_version in $bison_version_list; do
if test "$bison_version" = "$bison_check_version"; then
php_cv_bison_version="$bison_check_version (ok)"
break
fi
done
bison_version_num="`expr ${1} \* 100 + ${2}`"
if test $bison_version_num -ge $bison_version_min; then
php_cv_bison_version="$bison_version (ok)"
for bison_check_version in $bison_version_exclude; do
if test "$bison_version" = "$bison_check_version"; then
php_cv_bison_version=invalid
break
fi
done
fi
fi
])
fi
case $php_cv_bison_version in
""|invalid[)]
bison_msg="bison versions supported for regeneration of the Zend/PHP parsers: $bison_version_list (found: $bison_version)."
bison_msg="This bison version is not supported for regeneration of the Zend/PHP parsers (found: $bison_version, min: $bison_version_min, excluded: $bison_version_exclude)."
AC_MSG_WARN([$bison_msg])
YACC="exit 0;"
;;
+1
View File
@@ -2,6 +2,7 @@
Bug #30820 (static member conflict with $this->member silently ignored)
--INI--
error_reporting=4095
opcache.optimization_level=0
--FILE--
<?php
class Blah {
-2
View File
@@ -1,7 +1,5 @@
--TEST--
Fixed Bug #65784 (Segfault with finally)
--XFAIL--
This bug is not fixed in 5.5 due to ABI BC
--FILE--
<?php
function foo1() {
+14
View File
@@ -0,0 +1,14 @@
--TEST--
Bug #66252 (Problems in AST evaluation invalidating valid parent:: reference)
--FILE--
<?php
class A {
const HW = "this is A";
}
class B extends A {
const BHW = parent::HW . " extended by B";
}
const C = B::BHW;
echo C, "\n";
--EXPECT--
this is A extended by B
+13
View File
@@ -0,0 +1,13 @@
--TEST--
Class Property Expressions
--FILE--
<?php
class Foo {
const BAR = 1 << 0;
const BAZ = 1 << 1;
public $bar = self::BAR | self::BAZ;
}
echo (new Foo)->bar;
?>
--EXPECTF--
3
+20
View File
@@ -0,0 +1,20 @@
--TEST--
Static Class Property Expressions
--FILE--
<?php
class Foo {
public $b1 = 1 + 1;
public $b2 = 1 << 2;
public $b3 = "foo " . " bar " . " baz";
}
$f = new Foo;
var_dump(
$f->b1,
$f->b2,
$f->b3
);
?>
--EXPECT--
int(2)
int(4)
string(13) "foo bar baz"
+4 -1
View File
@@ -21,8 +21,11 @@ var_dump($x = $test->test($y));
var_dump($y, $x);
?>
--EXPECT--
--EXPECTF--
Notice: Only variable references should be returned by reference in %sclosure_018.php on line 7
int(4)
Notice: Only variable references should be returned by reference in %sclosure_018.php on line 7
int(16)
int(16)
int(16)
+3
View File
@@ -20,7 +20,10 @@ test();
?>
--EXPECTF--
Notice: Only variable references should be returned by reference in %sclosure_019.php on line 4
int(9)
Notice: Only variable references should be returned by reference in %sclosure_019.php on line 4
int(81)
Fatal error: Cannot pass parameter 1 by reference in %s on line %d
+91
View File
@@ -0,0 +1,91 @@
--TEST--
Constant Expressions
--FILE--
<?php
const T_1 = 1 << 1;
const T_2 = 1 / 2;
const T_3 = 1.5 + 1.5;
const T_4 = "foo" . "bar";
const T_5 = (1.5 + 1.5) * 2;
const T_6 = "foo" . 2 . 3 . 4.0;
const T_7 = __LINE__;
const T_8 = <<<ENDOFSTRING
This is a test string
ENDOFSTRING;
const T_9 = ~-1;
const T_10 = (-1?:1) + (0?2:3);
const T_11 = 1 && 0;
const T_12 = 1 and 1;
const T_13 = 0 || 0;
const T_14 = 1 or 0;
const T_15 = 1 xor 1;
const T_16 = 1 xor 0;
const T_17 = 1 < 0;
const T_18 = 0 <= 0;
const T_19 = 1 > 0;
const T_20 = 1 >= 0;
const T_21 = 1 === 1;
const T_22 = 1 !== 1;
const T_23 = 0 != "0";
const T_24 = 1 == "1";
// Test order of operations
const T_25 = 1 + 2 * 3;
// Test for memory leaks
const T_26 = "1" + 2 + "3";
var_dump(T_1);
var_dump(T_2);
var_dump(T_3);
var_dump(T_4);
var_dump(T_5);
var_dump(T_6);
var_dump(T_7);
var_dump(T_8);
var_dump(T_9);
var_dump(T_10);
var_dump(T_11);
var_dump(T_12);
var_dump(T_13);
var_dump(T_14);
var_dump(T_15);
var_dump(T_16);
var_dump(T_17);
var_dump(T_18);
var_dump(T_19);
var_dump(T_20);
var_dump(T_21);
var_dump(T_22);
var_dump(T_23);
var_dump(T_24);
var_dump(T_25);
var_dump(T_26);
?>
--EXPECT--
int(2)
float(0.5)
float(3)
string(6) "foobar"
float(6)
string(6) "foo234"
int(8)
string(21) "This is a test string"
int(0)
int(2)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(true)
bool(true)
bool(true)
bool(false)
bool(false)
bool(true)
int(7)
int(6)
@@ -0,0 +1,43 @@
--TEST--
Constant scalar expressions with autoloading and classes
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.optimization_level=-1
--SKIPIF--
<?php if (!extension_loaded('Zend OPcache') || php_sapi_name() != "cli") die("skip CLI only"); ?>
--FILE--
<?php
# This test validates that autoloading works for common const expression (AST) use cases
$classlist = [
'A'=> 'class A { const HW = "this is A"; }',
'B'=> 'class B extends A { const HW = parent::HW." extended by B"; }',
'space1\C' => 'namespace space1; class C { const HW = "this is space1\C"; }',
'D' => 'class D { const HW = \space1\C::HW." extented by D"; }',
'trE' => 'trait trE { public static function getHW() { return parent::HW; } }',
'E' => 'class E extends B { use trE; }',
'F' => 'class F { const XX = "this is F"; }',
'G' => 'class G extends F { const XX = parent::XX." extended by G"; public static function get_me($x = "got ".self::XX) { return $x; } }',
];
spl_autoload_register(function ($class) use ($classlist) {
if (isset($classlist[$class])) {
eval($classlist[$class]);
} else {
die("Cannot autoload $class\n");
}
});
printf("B::HW = %s\n", B::HW);
printf("D::HW = %s\n", D::HW);
printf("E::getHW() = %s\n", E::getHW());
printf("G::get_me() = %s\n", G::get_me());
?>
--EXPECT--
B::HW = this is A extended by B
D::HW = this is space1\C extented by D
E::getHW() = this is A extended by B
G::get_me() = got this is F extended by G
@@ -0,0 +1,11 @@
--TEST--
Dynamic Constant Expressions
--FILE--
<?php
const FOO = 1;
const BAR = FOO | 2;
echo BAR;
?>
--EXPECTF--
3
+14
View File
@@ -0,0 +1,14 @@
--TEST--
jmp into a finally block 01
--FILE--
<?php
function foo() {
goto test;
try {
} finally {
test:
}
}
?>
--EXPECTF--
Fatal error: jump into a finally block is disallowed in %sfinally_goto_001.php on line %d
+14
View File
@@ -0,0 +1,14 @@
--TEST--
jmp into a finally block 02
--FILE--
<?php
function foo() {
try {
goto test;
} finally {
test:
}
}
?>
--EXPECTF--
Fatal error: jump into a finally block is disallowed in %sfinally_goto_002.php on line %d
+15
View File
@@ -0,0 +1,15 @@
--TEST--
jmp into a finally block 03
--FILE--
<?php
function foo() {
try {
} finally {
goto test;
test:
}
}
echo "okey";
?>
--EXPECTF--
okey
+14
View File
@@ -0,0 +1,14 @@
--TEST--
jmp into a finally block 03
--FILE--
<?php
function foo() {
try {
} finally {
test:
}
goto test;
}
?>
--EXPECTF--
Fatal error: jump into a finally block is disallowed in %sfinally_goto_004.php on line %d
+17
View File
@@ -0,0 +1,17 @@
--TEST--
Function Argument Parsing #003
--FILE--
<?php
const a = 10;
function t1($a = 1 + 1, $b = 1 << 2, $c = "foo" . "bar", $d = a * 10) {
var_dump($a, $b, $c, $d);
}
t1();
?>
--EXPECT--
int(2)
int(4)
string(6) "foobar"
int(100)
+20
View File
@@ -0,0 +1,20 @@
--TEST--
Incompatible context call (non-internal function)
--INI--
error_reporting=E_ALL
--FILE--
<?php
class A {
function foo() { var_dump(get_class($this)); }
}
class B {
function bar() { A::foo(); }
}
$b = new B;
$b->bar();
?>
--EXPECTF--
Deprecated: Non-static method A::foo() should not be called statically, assuming $this from incompatible context in %s on line %d
string(1) "B"
+29
View File
@@ -0,0 +1,29 @@
--TEST--
Static Variable Expressions
--FILE--
<?php
const bar = 2, baz = bar + 1;
function foo() {
static $a = 1 + 1;
static $b = [bar => 1 + 1, baz * 2 => 1 << 2];
static $c = [1 => bar, 3 => baz];
var_dump($a, $b, $c);
}
foo();
?>
--EXPECT--
int(2)
array(2) {
[2]=>
int(2)
[6]=>
int(4)
}
array(2) {
[1]=>
int(2)
[3]=>
int(3)
}
+26
View File
@@ -0,0 +1,26 @@
--TEST--
aliasing imported constants to resolve naming conflicts
--FILE--
<?php
namespace foo {
const baz = 42;
}
namespace bar {
const baz = 43;
}
namespace {
use const foo\baz as foo_baz,
bar\baz as bar_baz;
var_dump(foo_baz);
var_dump(bar_baz);
echo "Done\n";
}
?>
--EXPECT--
int(42)
int(43)
Done
+22
View File
@@ -0,0 +1,22 @@
--TEST--
import namespaced constant
--FILE--
<?php
namespace foo\bar {
const baz = 42;
const qux = 43;
}
namespace {
use const foo\bar\baz, foo\bar\qux;
var_dump(baz);
var_dump(qux);
echo "Done\n";
}
?>
--EXPECT--
int(42)
int(43)
Done
+12
View File
@@ -0,0 +1,12 @@
--TEST--
importing const with same name but different case
--FILE--
<?php
namespace {
use const foo\bar;
use const foo\BAR;
}
?>
--EXPECT--
+21
View File
@@ -0,0 +1,21 @@
--TEST--
use const statements with conflicting names
--FILE--
<?php
namespace foo {
const baz = 42;
}
namespace bar {
const baz = 42;
}
namespace {
use const foo\baz, bar\baz;
echo "Done\n";
}
?>
--EXPECTF--
Fatal error: Cannot use const bar\baz as baz because the name is already in use in %s on line %d
@@ -0,0 +1,18 @@
--TEST--
use and use const with the same alias
--FILE--
<?php
namespace {
const foo = 'foo';
}
namespace x {
use foo as bar;
use const foo as bar;
var_dump(bar);
}
?>
--EXPECT--
string(3) "foo"
+14
View File
@@ -0,0 +1,14 @@
--TEST--
defining const with same name as imported should fail
--FILE--
<?php
namespace {
use const foo\bar;
const bar = 42;
}
?>
--EXPECTF--
Fatal error: Cannot declare const bar because the name is already in use in %s on line %d
@@ -0,0 +1,18 @@
--TEST--
using const with same name as defined should fail
--FILE--
<?php
namespace {
const bar = 42;
use const foo\bar;
}
namespace {
echo "Done";
}
?>
--EXPECTF--
Fatal error: Cannot use const foo\bar as bar because the name is already in use in %s on line %d
@@ -0,0 +1,5 @@
<?php
namespace foo;
const bar = 'local bar';
@@ -0,0 +1,5 @@
<?php
namespace foo;
const PHP_VERSION = 42;
@@ -0,0 +1,3 @@
<?php
const bar = 'global bar';
@@ -0,0 +1,3 @@
<?php
const baz = NULL;
@@ -0,0 +1,14 @@
--TEST--
non-existent imported constants should not be looked up in the global table
--FILE--
<?php
require 'includes/global_baz.php';
use const foo\bar\baz;
var_dump(baz);
?>
--EXPECTF--
Notice: Use of undefined constant baz - assumed 'baz' in %s on line %d
string(3) "baz"
+12
View File
@@ -0,0 +1,12 @@
--TEST--
Allow self and parent in use const statement
--FILE--
<?php
namespace {
use const self as foo;
use const parent as bar;
}
?>
--EXPECT--
+16
View File
@@ -0,0 +1,16 @@
--TEST--
shadowing a global core constant with a local version
--FILE--
<?php
require 'includes/foo_php_version.php';
use const foo\PHP_VERSION;
var_dump(PHP_VERSION);
echo "Done\n";
?>
--EXPECTF--
int(42)
Done
+25
View File
@@ -0,0 +1,25 @@
--TEST--
shadowing a global constant with a local version
--FILE--
<?php
namespace {
require 'includes/global_bar.php';
require 'includes/foo_bar.php';
}
namespace {
var_dump(bar);
}
namespace {
use const foo\bar;
var_dump(bar);
echo "Done\n";
}
?>
--EXPECT--
string(10) "global bar"
string(9) "local bar"
Done
+30
View File
@@ -0,0 +1,30 @@
--TEST--
aliasing imported functions to resolve naming conflicts
--FILE--
<?php
namespace foo {
function baz() {
return 'foo.baz';
}
}
namespace bar {
function baz() {
return 'bar.baz';
}
}
namespace {
use function foo\baz as foo_baz,
bar\baz as bar_baz;
var_dump(foo_baz());
var_dump(bar_baz());
echo "Done\n";
}
?>
--EXPECT--
string(7) "foo.baz"
string(7) "bar.baz"
Done
+26
View File
@@ -0,0 +1,26 @@
--TEST--
import namespaced function
--FILE--
<?php
namespace foo\bar {
function baz() {
return 'foo.bar.baz';
}
function qux() {
return baz();
}
}
namespace {
use function foo\bar\baz, foo\bar\qux;
var_dump(baz());
var_dump(qux());
echo "Done\n";
}
?>
--EXPECT--
string(11) "foo.bar.baz"
string(11) "foo.bar.baz"
Done
@@ -0,0 +1,13 @@
--TEST--
importing function with same name but different case should fail
--FILE--
<?php
namespace {
use function foo\bar;
use function foo\BAR;
}
?>
--EXPECTF--
Fatal error: Cannot use function foo\BAR as BAR because the name is already in use in %s on line %d
@@ -0,0 +1,17 @@
--TEST--
function that is conditionally defined at runtime should not cause compiler error
--FILE--
<?php
if (0) {
function foo() {
}
}
use function bar\foo;
echo "Done";
?>
--EXPECT--
Done
@@ -0,0 +1,25 @@
--TEST--
use function statements with conflicting names
--FILE--
<?php
namespace foo {
function baz() {
return 'foo.baz';
}
}
namespace bar {
function baz() {
return 'bar.baz';
}
}
namespace {
use function foo\baz, bar\baz;
echo "Done\n";
}
?>
--EXPECTF--
Fatal error: Cannot use function bar\baz as baz because the name is already in use in %s on line %d
@@ -0,0 +1,20 @@
--TEST--
use and use function with the same alias
--FILE--
<?php
namespace {
function foo() {
return 'foo';
}
}
namespace x {
use foo as bar;
use function foo as bar;
var_dump(bar());
}
?>
--EXPECT--
string(3) "foo"
@@ -0,0 +1,23 @@
--TEST--
use const and use function with the same alias
--FILE--
<?php
namespace {
const foo = 'foo.const';
function foo() {
return 'foo.function';
}
}
namespace x {
use const foo as bar;
use function foo as bar;
var_dump(bar);
var_dump(bar());
}
?>
--EXPECT--
string(9) "foo.const"
string(12) "foo.function"
@@ -0,0 +1,14 @@
--TEST--
defining function with same name as imported should fail
--FILE--
<?php
namespace {
use function foo\bar;
function bar() {}
}
?>
--EXPECTF--
Fatal error: Cannot declare function bar because the name is already in use in %s on line %d
@@ -0,0 +1,18 @@
--TEST--
using function with same name as defined should fail
--FILE--
<?php
namespace {
function bar() {}
use function foo\bar;
}
namespace {
echo "Done";
}
?>
--EXPECTF--
Fatal error: Cannot use function foo\bar as bar because the name is already in use in %s on line %d
@@ -0,0 +1,23 @@
--TEST--
use function should ignore namespaced constants
--FILE--
<?php
namespace foo {
const bar = 42;
}
namespace {
const bar = 43;
}
namespace {
use function foo\bar;
var_dump(bar);
echo "Done\n";
}
?>
--EXPECT--
int(43)
Done
@@ -0,0 +1,7 @@
<?php
namespace foo;
function bar() {
return 'local bar';
}
@@ -0,0 +1,7 @@
<?php
namespace foo;
function strlen($str) {
return 4;
}
@@ -0,0 +1,5 @@
<?php
function bar() {
return 'global bar';
}
@@ -0,0 +1,4 @@
<?php
function baz() {
}
@@ -0,0 +1,13 @@
--TEST--
non-existent imported functions should not be looked up in the global table
--FILE--
<?php
require 'includes/global_baz.php';
use function foo\bar\baz;
var_dump(baz());
?>
--EXPECTF--
Fatal error: Call to undefined function foo\bar\baz() in %s on line %d
@@ -0,0 +1,18 @@
--TEST--
non-existent imported functions should not be looked up in the global table
--FILE--
<?php
namespace {
function test() {
echo "NO!";
}
}
namespace foo {
use function bar\test;
test();
}
?>
--EXPECTF--
Fatal error: Call to undefined function bar\test() in %s on line %d
+12
View File
@@ -0,0 +1,12 @@
--TEST--
Allow self and parent in use function statement
--FILE--
<?php
namespace {
use function self as foo;
use function parent as bar;
}
?>
--EXPECT--
+16
View File
@@ -0,0 +1,16 @@
--TEST--
shadowing a global core function with a local version
--FILE--
<?php
require 'includes/foo_strlen.php';
use function foo\strlen;
var_dump(strlen('foo bar baz'));
echo "Done\n";
?>
--EXPECT--
int(4)
Done
@@ -0,0 +1,25 @@
--TEST--
shadowing a global function with a local version
--FILE--
<?php
namespace {
require 'includes/global_bar.php';
require 'includes/foo_bar.php';
}
namespace {
var_dump(bar());
}
namespace {
use function foo\bar;
var_dump(bar());
echo "Done\n";
}
?>
--EXPECT--
string(10) "global bar"
string(9) "local bar"
Done
@@ -0,0 +1,17 @@
--TEST--
It's possible to add additional optional arguments with matching signature
--FILE--
<?php
interface DB {
public function query($query, string ...$params);
}
class MySQL implements DB {
public function query($query, string $extraParam = null, string ...$params) { }
}
?>
===DONE===
--EXPECT--
===DONE===
@@ -0,0 +1,16 @@
--TEST--
Additional optional parameters must have a matching prototype
--FILE--
<?php
interface DB {
public function query($query, string ...$params);
}
class MySQL implements DB {
public function query($query, int $extraParam = null, string ...$params) { }
}
?>
--EXPECTF--
Fatal error: Declaration of MySQL::query() must be compatible with DB::query($query, string ...$params) in %s on line %d
+57
View File
@@ -0,0 +1,57 @@
--TEST--
Basic variadic function
--FILE--
<?php
function test1(... $args) {
var_dump($args);
}
test1();
test1(1);
test1(1, 2, 3);
function test2($arg1, $arg2, ...$args) {
var_dump($arg1, $arg2, $args);
}
test2(1, 2);
test2(1, 2, 3);
test2(1, 2, 3, 4, 5);
?>
--EXPECT--
array(0) {
}
array(1) {
[0]=>
int(1)
}
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
int(1)
int(2)
array(0) {
}
int(1)
int(2)
array(1) {
[0]=>
int(3)
}
int(1)
int(2)
array(3) {
[0]=>
int(3)
[1]=>
int(4)
[2]=>
int(5)
}
+24
View File
@@ -0,0 +1,24 @@
--TEST--
Variadic arguments with by-reference passing
--FILE--
<?php
function test(&... $args) {
$i = 0;
foreach ($args as &$arg) {
$arg = $i++;
}
}
test();
test($a);
var_dump($a);
test($b, $c, $d);
var_dump($b, $c, $d);
?>
--EXPECT--
int(0)
int(0)
int(1)
int(2)
+12
View File
@@ -0,0 +1,12 @@
--TEST--
By-ref variadics enforce the reference
--FILE--
<?php
function test(&... $args) { }
test(1);
?>
--EXPECTF--
Fatal error: Only variables can be passed by reference in %s on line %d
+10
View File
@@ -0,0 +1,10 @@
--TEST--
Variadic argument cannot have a default value
--FILE--
<?php
function test(...$args = 123) {}
?>
--EXPECTF--
Fatal error: Variadic parameter cannot have a default value in %s on line %d
@@ -0,0 +1,16 @@
--TEST--
It's not possible to turn a variadic function into a non-variadic one
--FILE--
<?php
interface DB {
public function query($query, ...$params);
}
class MySQL implements DB {
public function query($query, $params) { }
}
?>
--EXPECTF--
Fatal error: Declaration of MySQL::query() must be compatible with DB::query($query, ...$params) in %s on line %d
+10
View File
@@ -0,0 +1,10 @@
--TEST--
Only the last argument can be variadic
--FILE--
<?php
function test($foo, ...$bar, $baz) {}
?>
--EXPECTF--
Fatal error: Only the last parameter can be variadic in %s on line %d
+49
View File
@@ -0,0 +1,49 @@
--TEST--
Optional parameter before variadic parameter
--FILE--
<?php
function fn($reqParam, $optParam = null, ...$params) {
var_dump($reqParam, $optParam, $params);
}
fn(1);
fn(1, 2);
fn(1, 2, 3);
fn(1, 2, 3, 4);
fn(1, 2, 3, 4, 5);
?>
--EXPECT--
int(1)
NULL
array(0) {
}
int(1)
int(2)
array(0) {
}
int(1)
int(2)
array(1) {
[0]=>
int(3)
}
int(1)
int(2)
array(2) {
[0]=>
int(3)
[1]=>
int(4)
}
int(1)
int(2)
array(3) {
[0]=>
int(3)
[1]=>
int(4)
[2]=>
int(5)
}
@@ -0,0 +1,20 @@
--TEST--
It's not possible to remove required parameter before a variadic parameter
--FILE--
<?php
/* Theoretically this should be valid because it weakens the constraint, but
* PHP does not allow this (for non-variadics), so I'm not allowing it here, too,
* to stay consistent. */
interface DB {
public function query($query, ...$params);
}
class MySQL implements DB {
public function query(...$params) { }
}
?>
--EXPECTF--
Fatal error: Declaration of MySQL::query() must be compatible with DB::query($query, ...$params) in %s on line %d
+36
View File
@@ -0,0 +1,36 @@
--TEST--
Variadic arguments enforce typehints
--FILE--
<?php
function test(array... $args) {
var_dump($args);
}
test();
test([0], [1], [2]);
test([0], [1], 2);
?>
--EXPECTF--
array(0) {
}
array(3) {
[0]=>
array(1) {
[0]=>
int(0)
}
[1]=>
array(1) {
[0]=>
int(1)
}
[2]=>
array(1) {
[0]=>
int(2)
}
}
Catchable fatal error: Argument 3 passed to test() must be of the type array, integer given, called in %s on line %d
@@ -0,0 +1,33 @@
--TEST--
Error suppression for typehints on variadic arguments works
--FILE--
<?php
function test(array... $args) {
var_dump($args);
}
set_error_handler(function($errno, $errstr) {
var_dump($errstr);
return true;
});
test([0], [1], 2);
?>
--EXPECTF--
string(%d) "Argument 3 passed to test() must be of the type array, integer given, called in %s on line %d and defined"
array(3) {
[0]=>
array(1) {
[0]=>
int(0)
}
[1]=>
array(1) {
[0]=>
int(1)
}
[2]=>
int(2)
}
@@ -0,0 +1,16 @@
--TEST--
Variadic arguments must have compatible passing modes
--FILE--
<?php
interface DB {
public function query($query, &...$params);
}
class MySQL implements DB {
public function query($query, ...$params) { }
}
?>
--EXPECTF--
Fatal error: Declaration of MySQL::query() must be compatible with DB::query($query, &...$params) in %s on line %d
@@ -0,0 +1,16 @@
--TEST--
Typehints for variadic arguments have to be compatible
--FILE--
<?php
interface DB {
public function query($query, string ...$params);
}
class MySQL implements DB {
public function query($query, int ...$params) { }
}
?>
--EXPECTF--
Fatal error: Declaration of MySQL::query() must be compatible with DB::query($query, string ...$params) in %s on line %d
@@ -0,0 +1,17 @@
--TEST--
A non-variadic function can be turned into a variadic one
--FILE--
<?php
interface DB {
public function query($query);
}
class MySQL implements DB {
public function query($query, ...$params) { }
}
?>
===DONE===
--EXPECT--
===DONE===
@@ -0,0 +1,14 @@
--TEST--
Zend signed multiply 32-bit
--SKIPIF--
<?php if ((1 << 31) > 0) print "skip Running on 64-bit target"; ?>
--FILE--
<?php
var_dump(0x8000 * -0xffff);
var_dump(0x8001 * 0xfffe);
var_dump(0x8001 * -0xffff);
?>
--EXPECTF--
int(-2147450880)
int(2147483646)
float(-2147516415)
@@ -0,0 +1,14 @@
--TEST--
Zend signed multiply 64-bit
--SKIPIF--
<?php if ((1 << 31) < 0) print "skip Running on 32-bit target"; ?>
--FILE--
<?php
var_dump(0x80000000 * -0xffffffff);
var_dump(0x80000001 * 0xfffffffe);
var_dump(0x80000001 * -0xffffffff);
?>
--EXPECTF--
int(-9223372034707292160)
int(9223372036854775806)
float(-9.2233720390023E+18)
+16 -2
View File
@@ -30,6 +30,7 @@
#include "zend_ini.h"
#include "zend_vm.h"
#include "zend_dtrace.h"
#include "zend_virtual_cwd.h"
#ifdef ZTS
# define GLOBAL_FUNCTION_TABLE global_function_table
@@ -652,6 +653,8 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions TS
start_memory_manager(TSRMLS_C);
virtual_cwd_startup(); /* Could use shutdown to free the main cwd but it would just slow it down for CGI */
#if defined(__FreeBSD__) || defined(__DragonFly__)
/* FreeBSD and DragonFly floating point precision fix */
fpsetmask(0);
@@ -802,9 +805,14 @@ void zend_post_startup(TSRMLS_D) /* {{{ */
compiler_globals_ctor(compiler_globals, tsrm_ls);
}
free(EG(zend_constants));
virtual_cwd_deactivate(TSRMLS_C);
executor_globals_ctor(executor_globals, tsrm_ls);
global_persistent_list = &EG(persistent_list);
zend_copy_ini_directives(TSRMLS_C);
#else
virtual_cwd_deactivate(TSRMLS_C);
#endif
}
/* }}} */
@@ -820,6 +828,9 @@ void zend_shutdown(TSRMLS_D) /* {{{ */
zend_destroy_rsrc_list(&EG(persistent_list) TSRMLS_CC);
zend_destroy_modules();
virtual_cwd_deactivate(TSRMLS_C);
virtual_cwd_shutdown();
zend_hash_destroy(GLOBAL_FUNCTION_TABLE);
zend_hash_destroy(GLOBAL_CLASS_TABLE);
@@ -908,8 +919,11 @@ ZEND_API char *get_zend_version(void) /* {{{ */
}
/* }}} */
void zend_activate(TSRMLS_D) /* {{{ */
ZEND_API void zend_activate(TSRMLS_D) /* {{{ */
{
#ifdef ZTS
virtual_cwd_activate(TSRMLS_C);
#endif
gc_reset(TSRMLS_C);
init_compiler(TSRMLS_C);
init_executor(TSRMLS_C);
@@ -925,7 +939,7 @@ void zend_call_destructors(TSRMLS_D) /* {{{ */
}
/* }}} */
void zend_deactivate(TSRMLS_D) /* {{{ */
ZEND_API void zend_deactivate(TSRMLS_D) /* {{{ */
{
/* we're no longer executing anything */
EG(opline_ptr) = NULL;
+19 -12
View File
@@ -22,7 +22,7 @@
#ifndef ZEND_H
#define ZEND_H
#define ZEND_VERSION "2.5.0"
#define ZEND_VERSION "2.6.0-dev"
#define ZEND_ENGINE_2
@@ -193,7 +193,7 @@ char *alloca ();
#endif
#define restrict __restrict__
#if (HAVE_ALLOCA || (defined (__GNUC__) && __GNUC__ >= 2)) && !(defined(ZTS) && defined(ZEND_WIN32)) && !(defined(ZTS) && defined(NETWARE)) && !(defined(ZTS) && defined(HPUX)) && !defined(DARWIN)
#if (HAVE_ALLOCA || (defined (__GNUC__) && __GNUC__ >= 2)) && !(defined(ZTS) && defined(NETWARE)) && !(defined(ZTS) && defined(HPUX)) && !defined(DARWIN)
# define ZEND_ALLOCA_MAX_SIZE (32 * 1024)
# define ALLOCA_FLAG(name) \
zend_bool name;
@@ -317,6 +317,7 @@ typedef struct _zend_object {
} zend_object;
#include "zend_object_handlers.h"
#include "zend_ast.h"
typedef union _zvalue_value {
long lval; /* long value */
@@ -327,6 +328,7 @@ typedef union _zvalue_value {
} str;
HashTable *ht; /* hash table value */
zend_object_value obj;
zend_ast *ast;
} zvalue_value;
struct _zval_struct {
@@ -587,7 +589,8 @@ typedef int (*zend_write_func_t)(const char *str, uint str_length);
#define IS_RESOURCE 7
#define IS_CONSTANT 8
#define IS_CONSTANT_ARRAY 9
#define IS_CALLABLE 10
#define IS_CONSTANT_AST 10
#define IS_CALLABLE 11
/* Ugly hack to support constants as static array indices */
#define IS_CONSTANT_TYPE_MASK 0x00f
@@ -597,6 +600,8 @@ typedef int (*zend_write_func_t)(const char *str, uint str_length);
#define IS_LEXICAL_REF 0x040
#define IS_CONSTANT_IN_NAMESPACE 0x100
#define IS_CONSTANT_TYPE(type) (((type) & IS_CONSTANT_TYPE_MASK) >= IS_CONSTANT && ((type) & IS_CONSTANT_TYPE_MASK) <= IS_CONSTANT_AST)
/* overloaded elements data types */
#define OE_IS_ARRAY (1<<0)
#define OE_IS_OBJECT (1<<1)
@@ -651,12 +656,14 @@ ZEND_API void zend_print_zval_r_ex(zend_write_func_t write_func, zval *expr, int
ZEND_API void zend_output_debug_string(zend_bool trigger_break, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
END_EXTERN_C()
void zend_activate(TSRMLS_D);
void zend_deactivate(TSRMLS_D);
void zend_call_destructors(TSRMLS_D);
void zend_activate_modules(TSRMLS_D);
void zend_deactivate_modules(TSRMLS_D);
void zend_post_deactivate_modules(TSRMLS_D);
BEGIN_EXTERN_C()
ZEND_API void zend_activate(TSRMLS_D);
ZEND_API void zend_deactivate(TSRMLS_D);
ZEND_API void zend_call_destructors(TSRMLS_D);
ZEND_API void zend_activate_modules(TSRMLS_D);
ZEND_API void zend_deactivate_modules(TSRMLS_D);
ZEND_API void zend_post_deactivate_modules(TSRMLS_D);
END_EXTERN_C()
#if ZEND_DEBUG
#define Z_DBG(expr) (expr)
@@ -670,8 +677,8 @@ END_EXTERN_C()
/* FIXME: Check if we can save if (ptr) too */
#define STR_FREE(ptr) if (ptr && !IS_INTERNED(ptr)) { efree(ptr); }
#define STR_FREE_REL(ptr) if (ptr && !IS_INTERNED(ptr)) { efree_rel(ptr); }
#define STR_FREE(ptr) if (ptr) { str_efree(ptr); }
#define STR_FREE_REL(ptr) if (ptr) { str_efree_rel(ptr); }
#define STR_EMPTY_ALLOC() estrndup("", sizeof("")-1)
@@ -683,7 +690,7 @@ END_EXTERN_C()
#define ZEND_WRITE_EX(str, str_len) write_func((str), (str_len))
#define ZEND_PUTS(str) zend_write((str), strlen((str)))
#define ZEND_PUTS_EX(str) write_func((str), strlen((str)))
#define ZEND_PUTC(c) zend_write(&(c), 1), (c)
#define ZEND_PUTC(c) zend_write(&(c), 1)
BEGIN_EXTERN_C()
extern ZEND_API int (*zend_printf)(const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 1, 2);
+29 -26
View File
@@ -1010,7 +1010,7 @@ ZEND_API int _array_init(zval *arg, uint size ZEND_FILE_LINE_DC) /* {{{ */
{
ALLOC_HASHTABLE_REL(Z_ARRVAL_P(arg));
_zend_hash_init(Z_ARRVAL_P(arg), size, NULL, ZVAL_PTR_DTOR, 0 ZEND_FILE_LINE_RELAY_CC);
_zend_hash_init(Z_ARRVAL_P(arg), size, ZVAL_PTR_DTOR, 0 ZEND_FILE_LINE_RELAY_CC);
Z_TYPE_P(arg) = IS_ARRAY;
return SUCCESS;
}
@@ -1053,8 +1053,7 @@ ZEND_API void zend_merge_properties(zval *obj, HashTable *properties, int destro
static int zval_update_class_constant(zval **pp, int is_static, int offset TSRMLS_DC) /* {{{ */
{
if ((Z_TYPE_PP(pp) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT ||
(Z_TYPE_PP(pp) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT_ARRAY) {
if (IS_CONSTANT_TYPE(Z_TYPE_PP(pp))) {
zend_class_entry **scope = EG(in_execution)?&EG(scope):&CG(active_class_entry);
if ((*scope)->parent) {
@@ -1078,7 +1077,7 @@ static int zval_update_class_constant(zval **pp, int is_static, int offset TSRML
}
ce = ce->parent;
} while (ce);
}
return zval_update_constant(pp, (void*)1 TSRMLS_CC);
}
@@ -2029,7 +2028,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
const zend_function_entry *ptr = functions;
zend_function function, *reg_function;
zend_internal_function *internal_function = (zend_internal_function *)&function;
int count=0, unload=0, result=0;
int count=0, unload=0;
HashTable *target_function_table = function_table;
int error_type;
zend_function *ctor = NULL, *dtor = NULL, *clone = NULL, *__get = NULL, *__set = NULL, *__unset = NULL, *__isset = NULL, *__call = NULL, *__callstatic = NULL, *__tostring = NULL;
@@ -2037,6 +2036,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
int fname_len;
const char *lc_class_name = NULL;
int class_name_len = 0;
zend_ulong hash;
if (type==MODULE_PERSISTENT) {
error_type = E_CORE_WARNING;
@@ -2089,16 +2089,12 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
} else {
internal_function->required_num_args = info->required_num_args;
}
if (info->pass_rest_by_reference) {
if (info->pass_rest_by_reference == ZEND_SEND_PREFER_REF) {
internal_function->fn_flags |= ZEND_ACC_PASS_REST_PREFER_REF;
} else {
internal_function->fn_flags |= ZEND_ACC_PASS_REST_BY_REFERENCE;
}
}
if (info->return_reference) {
internal_function->fn_flags |= ZEND_ACC_RETURN_REFERENCE;
}
if (ptr->arg_info[ptr->num_args].is_variadic) {
internal_function->fn_flags |= ZEND_ACC_VARIADIC;
}
} else {
internal_function->arg_info = NULL;
internal_function->num_args = 0;
@@ -2135,16 +2131,25 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
}
fname_len = strlen(ptr->fname);
lowercase_name = zend_new_interned_string(zend_str_tolower_dup(ptr->fname, fname_len), fname_len + 1, 1 TSRMLS_CC);
if (IS_INTERNED(lowercase_name)) {
result = zend_hash_quick_add(target_function_table, lowercase_name, fname_len+1, INTERNED_HASH(lowercase_name), &function, sizeof(zend_function), (void**)&reg_function);
} else {
result = zend_hash_add(target_function_table, lowercase_name, fname_len+1, &function, sizeof(zend_function), (void**)&reg_function);
}
if (result == FAILURE) {
hash = str_hash(lowercase_name, fname_len);
if (zend_hash_quick_add(target_function_table, lowercase_name, fname_len+1, hash, &function, sizeof(zend_function), (void**)&reg_function) == FAILURE) {
unload=1;
str_efree(lowercase_name);
break;
}
/* If types of arguments have to be checked */
if (reg_function->common.arg_info && reg_function->common.num_args) {
int i;
for (i = 0; i < reg_function->common.num_args; i++) {
if (reg_function->common.arg_info[i].class_name ||
reg_function->common.arg_info[i].type_hint) {
reg_function->common.fn_flags |= ZEND_ACC_HAS_TYPE_HINTS;
break;
}
}
}
if (scope) {
/* Look for ctor, dtor, clone
* If it's an old-style constructor, store it only if we don't have
@@ -2388,7 +2393,7 @@ void module_destructor(zend_module_entry *module) /* {{{ */
}
/* }}} */
void zend_activate_modules(TSRMLS_D) /* {{{ */
ZEND_API void zend_activate_modules(TSRMLS_D) /* {{{ */
{
zend_module_entry **p = module_request_startup_handlers;
@@ -2417,7 +2422,7 @@ int module_registry_cleanup(zend_module_entry *module TSRMLS_DC) /* {{{ */
}
/* }}} */
void zend_deactivate_modules(TSRMLS_D) /* {{{ */
ZEND_API void zend_deactivate_modules(TSRMLS_D) /* {{{ */
{
EG(opline_ptr) = NULL; /* we're no longer executing anything */
@@ -2464,7 +2469,7 @@ static int exec_done_cb(zend_module_entry *module TSRMLS_DC) /* {{{ */
}
/* }}} */
void zend_post_deactivate_modules(TSRMLS_D) /* {{{ */
ZEND_API void zend_post_deactivate_modules(TSRMLS_D) /* {{{ */
{
if (EG(full_tables_cleanup)) {
zend_hash_apply(&module_registry, (apply_func_t) exec_done_cb TSRMLS_CC);
@@ -2493,6 +2498,7 @@ static zend_class_entry *do_register_internal_class(zend_class_entry *orig_class
{
zend_class_entry *class_entry = malloc(sizeof(zend_class_entry));
char *lowercase_name = emalloc(orig_class_entry->name_length + 1);
zend_ulong hash;
*class_entry = *orig_class_entry;
class_entry->type = ZEND_INTERNAL_CLASS;
@@ -2506,11 +2512,8 @@ static zend_class_entry *do_register_internal_class(zend_class_entry *orig_class
zend_str_tolower_copy(lowercase_name, orig_class_entry->name, class_entry->name_length);
lowercase_name = (char*)zend_new_interned_string(lowercase_name, class_entry->name_length + 1, 1 TSRMLS_CC);
if (IS_INTERNED(lowercase_name)) {
zend_hash_quick_update(CG(class_table), lowercase_name, class_entry->name_length+1, INTERNED_HASH(lowercase_name), &class_entry, sizeof(zend_class_entry *), NULL);
} else {
zend_hash_update(CG(class_table), lowercase_name, class_entry->name_length+1, &class_entry, sizeof(zend_class_entry *), NULL);
}
hash = str_hash(lowercase_name, class_entry->name_length);
zend_hash_quick_update(CG(class_table), lowercase_name, class_entry->name_length+1, hash, &class_entry, sizeof(zend_class_entry *), NULL);
str_efree(lowercase_name);
return class_entry;
}
+31 -19
View File
@@ -98,16 +98,18 @@ typedef struct _zend_fcall_info_cache {
#define ZEND_FE_END { NULL, NULL, NULL, 0, 0 }
#define ZEND_ARG_INFO(pass_by_ref, name) { #name, sizeof(#name)-1, NULL, 0, 0, 0, pass_by_ref},
#define ZEND_ARG_PASS_INFO(pass_by_ref) { NULL, 0, NULL, 0, 0, 0, pass_by_ref},
#define ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null) { #name, sizeof(#name)-1, #classname, sizeof(#classname)-1, IS_OBJECT, allow_null, pass_by_ref},
#define ZEND_ARG_ARRAY_INFO(pass_by_ref, name, allow_null) { #name, sizeof(#name)-1, NULL, 0, IS_ARRAY, allow_null, pass_by_ref},
#define ZEND_ARG_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) { #name, sizeof(#name)-1, NULL, 0, type_hint, allow_null, pass_by_ref},
#define ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, return_reference, required_num_args) \
#define ZEND_ARG_INFO(pass_by_ref, name) { #name, sizeof(#name)-1, NULL, 0, 0, pass_by_ref, 0, 0 },
#define ZEND_ARG_PASS_INFO(pass_by_ref) { NULL, 0, NULL, 0, 0, pass_by_ref, 0, 0 },
#define ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null) { #name, sizeof(#name)-1, #classname, sizeof(#classname)-1, IS_OBJECT, pass_by_ref, allow_null, 0 },
#define ZEND_ARG_ARRAY_INFO(pass_by_ref, name, allow_null) { #name, sizeof(#name)-1, NULL, 0, IS_ARRAY, pass_by_ref, allow_null, 0 },
#define ZEND_ARG_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) { #name, sizeof(#name)-1, NULL, 0, type_hint, pass_by_ref, allow_null, 0 },
#define ZEND_ARG_VARIADIC_INFO(pass_by_ref, name) { #name, sizeof(#name)-1, NULL, 0, 0, pass_by_ref, 0, 1 },
#define ZEND_BEGIN_ARG_INFO_EX(name, _unused, return_reference, required_num_args) \
static const zend_arg_info name[] = { \
{ NULL, 0, NULL, required_num_args, 0, return_reference, pass_rest_by_reference},
#define ZEND_BEGIN_ARG_INFO(name, pass_rest_by_reference) \
ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, ZEND_RETURN_VALUE, -1)
{ NULL, 0, NULL, required_num_args, 0, return_reference, 0, 0 },
#define ZEND_BEGIN_ARG_INFO(name, _unused) \
ZEND_BEGIN_ARG_INFO_EX(name, 0, ZEND_RETURN_VALUE, -1)
#define ZEND_END_ARG_INFO() };
/* Name macros */
@@ -594,22 +596,20 @@ END_EXTERN_C()
Z_TYPE_P(__z) = IS_STRING; \
} while (0)
#define ZVAL_ZVAL(z, zv, copy, dtor) { \
zend_uchar is_ref = Z_ISREF_P(z); \
zend_uint refcount = Z_REFCOUNT_P(z); \
ZVAL_COPY_VALUE(z, zv); \
#define ZVAL_ZVAL(z, zv, copy, dtor) do { \
zval *__z = (z); \
zval *__zv = (zv); \
ZVAL_COPY_VALUE(__z, __zv); \
if (copy) { \
zval_copy_ctor(z); \
zval_copy_ctor(__z); \
} \
if (dtor) { \
if (!copy) { \
ZVAL_NULL(zv); \
ZVAL_NULL(__zv); \
} \
zval_ptr_dtor(&zv); \
zval_ptr_dtor(&__zv); \
} \
Z_SET_ISREF_TO_P(z, is_ref); \
Z_SET_REFCOUNT_P(z, refcount); \
}
} while (0)
#define ZVAL_FALSE(z) ZVAL_BOOL(z, 0)
#define ZVAL_TRUE(z) ZVAL_BOOL(z, 1)
@@ -638,6 +638,18 @@ END_EXTERN_C()
#define RETURN_FALSE { RETVAL_FALSE; return; }
#define RETURN_TRUE { RETVAL_TRUE; return; }
#define RETVAL_ZVAL_FAST(z) do { \
zval *_z = (z); \
if (Z_ISREF_P(_z)) { \
RETVAL_ZVAL(_z, 1, 0); \
} else { \
zval_ptr_dtor(&return_value); \
Z_ADDREF_P(_z); \
*return_value_ptr = _z; \
} \
} while (0)
#define RETURN_ZVAL_FAST(z) { RETVAL_ZVAL_FAST(z); return; }
#define SET_VAR_STRING(n, v) { \
{ \
zval *var; \
+329
View File
@@ -0,0 +1,329 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2013 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 2.00 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.zend.com/license/2_00.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Bob Weinand <bwoebi@php.net> |
| Dmitry Stogov <dmitry@zend.com> |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#include "zend_ast.h"
#include "zend_API.h"
#include "zend_operators.h"
ZEND_API zend_ast *zend_ast_create_constant(zval *zv)
{
zend_ast *ast = emalloc(sizeof(zend_ast) + sizeof(zval));
ast->kind = ZEND_CONST;
ast->children = 0;
ast->u.val = (zval*)(ast + 1);
INIT_PZVAL_COPY(ast->u.val, zv);
return ast;
}
ZEND_API zend_ast* zend_ast_create_unary(uint kind, zend_ast *op0)
{
zend_ast *ast = emalloc(sizeof(zend_ast));
ast->kind = kind;
ast->children = 1;
(&ast->u.child)[0] = op0;
return ast;
}
ZEND_API zend_ast* zend_ast_create_binary(uint kind, zend_ast *op0, zend_ast *op1)
{
zend_ast *ast = emalloc(sizeof(zend_ast) + sizeof(zend_ast*));
ast->kind = kind;
ast->children = 2;
(&ast->u.child)[0] = op0;
(&ast->u.child)[1] = op1;
return ast;
}
ZEND_API zend_ast* zend_ast_create_ternary(uint kind, zend_ast *op0, zend_ast *op1, zend_ast *op2)
{
zend_ast *ast = emalloc(sizeof(zend_ast) + sizeof(zend_ast*) * 2);
ast->kind = kind;
ast->children = 3;
(&ast->u.child)[0] = op0;
(&ast->u.child)[1] = op1;
(&ast->u.child)[2] = op2;
return ast;
}
ZEND_API int zend_ast_is_ct_constant(zend_ast *ast)
{
int i;
if (ast->kind == ZEND_CONST) {
return !IS_CONSTANT_TYPE(Z_TYPE_P(ast->u.val));
} else {
for (i = 0; i < ast->children; i++) {
if ((&ast->u.child)[i]) {
if (!zend_ast_is_ct_constant((&ast->u.child)[i])) {
return 0;
}
}
}
return 1;
}
}
ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *scope TSRMLS_DC)
{
zval op1, op2;
switch (ast->kind) {
case ZEND_ADD:
zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
add_function(result, &op1, &op2 TSRMLS_CC);
zval_dtor(&op1);
zval_dtor(&op2);
break;
case ZEND_SUB:
zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
sub_function(result, &op1, &op2 TSRMLS_CC);
zval_dtor(&op1);
zval_dtor(&op2);
break;
case ZEND_MUL:
zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
mul_function(result, &op1, &op2 TSRMLS_CC);
zval_dtor(&op1);
zval_dtor(&op2);
break;
case ZEND_DIV:
zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
div_function(result, &op1, &op2 TSRMLS_CC);
zval_dtor(&op1);
zval_dtor(&op2);
break;
case ZEND_MOD:
zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
mod_function(result, &op1, &op2 TSRMLS_CC);
zval_dtor(&op1);
zval_dtor(&op2);
break;
case ZEND_SL:
zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
shift_left_function(result, &op1, &op2 TSRMLS_CC);
zval_dtor(&op1);
zval_dtor(&op2);
break;
case ZEND_SR:
zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
shift_right_function(result, &op1, &op2 TSRMLS_CC);
zval_dtor(&op1);
zval_dtor(&op2);
break;
case ZEND_CONCAT:
zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
concat_function(result, &op1, &op2 TSRMLS_CC);
zval_dtor(&op1);
zval_dtor(&op2);
break;
case ZEND_BW_OR:
zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
bitwise_or_function(result, &op1, &op2 TSRMLS_CC);
zval_dtor(&op1);
zval_dtor(&op2);
break;
case ZEND_BW_AND:
zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
bitwise_and_function(result, &op1, &op2 TSRMLS_CC);
zval_dtor(&op1);
zval_dtor(&op2);
break;
case ZEND_BW_XOR:
zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
bitwise_xor_function(result, &op1, &op2 TSRMLS_CC);
zval_dtor(&op1);
zval_dtor(&op2);
break;
case ZEND_BW_NOT:
zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
bitwise_not_function(result, &op1 TSRMLS_CC);
zval_dtor(&op1);
break;
case ZEND_BOOL_NOT:
zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
boolean_not_function(result, &op1 TSRMLS_CC);
zval_dtor(&op1);
break;
case ZEND_BOOL_XOR:
zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
boolean_xor_function(result, &op1, &op2 TSRMLS_CC);
zval_dtor(&op1);
zval_dtor(&op2);
break;
case ZEND_IS_IDENTICAL:
zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
is_identical_function(result, &op1, &op2 TSRMLS_CC);
zval_dtor(&op1);
zval_dtor(&op2);
break;
case ZEND_IS_NOT_IDENTICAL:
zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
is_not_identical_function(result, &op1, &op2 TSRMLS_CC);
zval_dtor(&op1);
zval_dtor(&op2);
break;
case ZEND_IS_EQUAL:
zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
is_equal_function(result, &op1, &op2 TSRMLS_CC);
zval_dtor(&op1);
zval_dtor(&op2);
break;
case ZEND_IS_NOT_EQUAL:
zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
is_not_equal_function(result, &op1, &op2 TSRMLS_CC);
zval_dtor(&op1);
zval_dtor(&op2);
break;
case ZEND_IS_SMALLER:
zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
is_smaller_function(result, &op1, &op2 TSRMLS_CC);
zval_dtor(&op1);
zval_dtor(&op2);
break;
case ZEND_IS_SMALLER_OR_EQUAL:
zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
is_smaller_or_equal_function(result, &op1, &op2 TSRMLS_CC);
zval_dtor(&op1);
zval_dtor(&op2);
break;
case ZEND_CONST:
*result = *ast->u.val;
zval_copy_ctor(result);
if (IS_CONSTANT_TYPE(Z_TYPE_P(result))) {
zval_update_constant_ex(&result, (void *) 1, scope TSRMLS_CC);
}
break;
case ZEND_BOOL_AND:
zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
if (zend_is_true(&op1)) {
zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
ZVAL_BOOL(result, zend_is_true(&op2));
zval_dtor(&op2);
} else {
ZVAL_BOOL(result, 0);
}
zval_dtor(&op1);
break;
case ZEND_BOOL_OR:
zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
if (zend_is_true(&op1)) {
ZVAL_BOOL(result, 1);
} else {
zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC);
ZVAL_BOOL(result, zend_is_true(&op2));
zval_dtor(&op2);
}
zval_dtor(&op1);
break;
case ZEND_SELECT:
zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC);
if (zend_is_true(&op1)) {
if (!(&ast->u.child)[1]) {
*result = op1;
} else {
zend_ast_evaluate(result, (&ast->u.child)[1], scope TSRMLS_CC);
zval_dtor(&op1);
}
} else {
zend_ast_evaluate(result, (&ast->u.child)[2], scope TSRMLS_CC);
zval_dtor(&op1);
}
break;
case ZEND_UNARY_PLUS:
ZVAL_LONG(&op1, 0);
zend_ast_evaluate(&op2, (&ast->u.child)[0], scope TSRMLS_CC);
add_function(result, &op1, &op2 TSRMLS_CC);
zval_dtor(&op2);
break;
case ZEND_UNARY_MINUS:
ZVAL_LONG(&op1, 0);
zend_ast_evaluate(&op2, (&ast->u.child)[0], scope TSRMLS_CC);
sub_function(result, &op1, &op2 TSRMLS_CC);
zval_dtor(&op2);
break;
default:
zend_error(E_ERROR, "Unsupported constant expression");
}
}
ZEND_API zend_ast *zend_ast_copy(zend_ast *ast)
{
if (ast == NULL) {
return NULL;
} else if (ast->kind == ZEND_CONST) {
zend_ast *copy = zend_ast_create_constant(ast->u.val);
zval_copy_ctor(copy->u.val);
return copy;
} else {
switch (ast->children) {
case 1:
return zend_ast_create_unary(
ast->kind,
zend_ast_copy((&ast->u.child)[0]));
case 2:
return zend_ast_create_binary(
ast->kind,
zend_ast_copy((&ast->u.child)[0]),
zend_ast_copy((&ast->u.child)[1]));
case 3:
return zend_ast_create_ternary(
ast->kind,
zend_ast_copy((&ast->u.child)[0]),
zend_ast_copy((&ast->u.child)[1]),
zend_ast_copy((&ast->u.child)[2]));
}
}
return NULL;
}
ZEND_API void zend_ast_destroy(zend_ast *ast)
{
int i;
if (ast->kind == ZEND_CONST) {
zval_dtor(ast->u.val);
} else {
for (i = 0; i < ast->children; i++) {
if ((&ast->u.child)[i]) {
zend_ast_destroy((&ast->u.child)[i]);
}
}
}
efree(ast);
}
+61
View File
@@ -0,0 +1,61 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2013 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 2.00 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.zend.com/license/2_00.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Bob Weinand <bwoebi@php.net> |
| Dmitry Stogov <dmitry@zend.com> |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#ifndef ZEND_AST_H
#define ZEND_AST_H
typedef struct _zend_ast zend_ast;
#include "zend.h"
typedef enum _zend_ast_kind {
/* first 256 kinds are reserved for opcodes */
ZEND_CONST = 256,
ZEND_BOOL_AND,
ZEND_BOOL_OR,
ZEND_SELECT,
ZEND_UNARY_PLUS,
ZEND_UNARY_MINUS,
} zend_ast_kind;
struct _zend_ast {
unsigned short kind;
unsigned short children;
union {
zval *val;
zend_ast *child;
} u;
};
ZEND_API zend_ast *zend_ast_create_constant(zval *zv);
ZEND_API zend_ast *zend_ast_create_unary(uint kind, zend_ast *op0);
ZEND_API zend_ast *zend_ast_create_binary(uint kind, zend_ast *op0, zend_ast *op1);
ZEND_API zend_ast *zend_ast_create_ternary(uint kind, zend_ast *op0, zend_ast *op1, zend_ast *op2);
ZEND_API int zend_ast_is_ct_constant(zend_ast *ast);
ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *scope TSRMLS_DC);
ZEND_API zend_ast *zend_ast_copy(zend_ast *ast);
ZEND_API void zend_ast_destroy(zend_ast *ast);
#endif
+28 -18
View File
@@ -435,9 +435,7 @@ ZEND_FUNCTION(func_get_arg)
}
arg = *(p-(arg_count-requested_offset));
*return_value = *arg;
zval_copy_ctor(return_value);
INIT_PZVAL(return_value);
RETURN_ZVAL_FAST(arg);
}
/* }}} */
@@ -461,12 +459,17 @@ ZEND_FUNCTION(func_get_args)
array_init_size(return_value, arg_count);
for (i=0; i<arg_count; i++) {
zval *element;
zval *element, *arg;
ALLOC_ZVAL(element);
*element = **((zval **) (p-(arg_count-i)));
zval_copy_ctor(element);
INIT_PZVAL(element);
arg = *((zval **) (p-(arg_count-i)));
if (!Z_ISREF_P(arg)) {
element = arg;
Z_ADDREF_P(element);
} else {
ALLOC_ZVAL(element);
INIT_PZVAL_COPY(element, arg);
zval_copy_ctor(element);
}
zend_hash_next_index_insert(return_value->value.ht, &element, sizeof(zval *), NULL);
}
}
@@ -606,9 +609,9 @@ ZEND_FUNCTION(each)
Z_ADDREF_P(entry);
/* add the key elements */
switch (zend_hash_get_current_key_ex(target_hash, &string_key, &string_key_len, &num_key, 1, NULL)) {
switch (zend_hash_get_current_key_ex(target_hash, &string_key, &string_key_len, &num_key, 0, NULL)) {
case HASH_KEY_IS_STRING:
add_get_index_stringl(return_value, 0, string_key, string_key_len-1, (void **) &inserted_pointer, 0);
add_get_index_stringl(return_value, 0, string_key, string_key_len-1, (void **) &inserted_pointer, !IS_INTERNED(string_key));
break;
case HASH_KEY_IS_LONG:
add_get_index_long(return_value, 0, num_key, (void **) &inserted_pointer);
@@ -706,7 +709,7 @@ repeat:
zval_ptr_dtor(&val_free);
}
c.flags = case_sensitive; /* non persistent */
c.name = IS_INTERNED(name) ? name : zend_strndup(name, name_len);
c.name = str_strndup(name, name_len);
if(c.name == NULL) {
RETURN_FALSE;
}
@@ -943,11 +946,11 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value
/* this is necessary to make it able to work with default array
* properties, returned to user */
if (Z_TYPE_P(prop_copy) == IS_CONSTANT_ARRAY || (Z_TYPE_P(prop_copy) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) {
if (IS_CONSTANT_TYPE(Z_TYPE_P(prop_copy))) {
zval_update_constant(&prop_copy, 0 TSRMLS_CC);
}
add_assoc_zval(return_value, key, prop_copy);
zend_hash_update(Z_ARRVAL_P(return_value), key, key_len, &prop_copy, sizeof(zval*), NULL);
}
}
/* }}} */
@@ -1017,7 +1020,14 @@ ZEND_FUNCTION(get_object_vars)
zend_unmangle_property_name_ex(key, key_len - 1, &class_name, &prop_name, (int*) &prop_len);
/* Not separating references */
Z_ADDREF_PP(value);
add_assoc_zval_ex(return_value, prop_name, prop_len + 1, *value);
if (IS_INTERNED(key) && prop_name != key) {
/* we can't use substring of interned string as a new key */
char *tmp = estrndup(prop_name, prop_len);
add_assoc_zval_ex(return_value, tmp, prop_len + 1, *value);
efree(tmp);
} else {
add_assoc_zval_ex(return_value, prop_name, prop_len + 1, *value);
}
}
}
zend_hash_move_forward_ex(properties, &pos);
@@ -1388,12 +1398,11 @@ ZEND_FUNCTION(function_exists)
Creates an alias for user defined class */
ZEND_FUNCTION(class_alias)
{
char *class_name, *lc_name, *alias_name;
char *class_name, *alias_name;
zend_class_entry **ce;
int class_name_len, alias_name_len;
int found;
zend_bool autoload = 1;
ALLOCA_FLAG(use_heap)
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|b", &class_name, &class_name_len, &alias_name, &alias_name_len, &autoload) == FAILURE) {
return;
@@ -1474,6 +1483,7 @@ ZEND_FUNCTION(crash)
ZEND_FUNCTION(get_included_files)
{
char *entry;
uint entry_len;
if (zend_parse_parameters_none() == FAILURE) {
return;
@@ -1481,8 +1491,8 @@ ZEND_FUNCTION(get_included_files)
array_init(return_value);
zend_hash_internal_pointer_reset(&EG(included_files));
while (zend_hash_get_current_key(&EG(included_files), &entry, NULL, 1) == HASH_KEY_IS_STRING) {
add_next_index_string(return_value, entry, 0);
while (zend_hash_get_current_key_ex(&EG(included_files), &entry, &entry_len, NULL, 0, NULL) == HASH_KEY_IS_STRING) {
add_next_index_stringl(return_value, entry, entry_len-1, !IS_INTERNED(entry));
zend_hash_move_forward(&EG(included_files));
}
}
+2 -8
View File
@@ -59,14 +59,8 @@ ZEND_METHOD(Closure, __invoke) /* {{{ */
} else if (call_user_function_ex(CG(function_table), NULL, this_ptr, &closure_result_ptr, ZEND_NUM_ARGS(), arguments, 1, NULL TSRMLS_CC) == FAILURE) {
RETVAL_FALSE;
} else if (closure_result_ptr) {
if (Z_ISREF_P(closure_result_ptr) && return_value_ptr) {
if (return_value) {
zval_ptr_dtor(&return_value);
}
*return_value_ptr = closure_result_ptr;
} else {
RETVAL_ZVAL(closure_result_ptr, 1, 1);
}
zval_ptr_dtor(&return_value);
*return_value_ptr = closure_result_ptr;
}
efree(arguments);
+546 -319
View File
File diff suppressed because it is too large Load Diff
+37 -23
View File
@@ -23,6 +23,7 @@
#define ZEND_COMPILE_H
#include "zend.h"
#include "zend_ast.h"
#ifdef HAVE_STDARG_H
# include <stdarg.h>
@@ -74,7 +75,7 @@ typedef struct _zend_literal {
#define Z_HASH_P(zv) \
(((zend_literal*)(zv))->hash_value)
typedef union _znode_op {
typedef union _znode_op {
zend_uint constant;
zend_uint var;
zend_uint num;
@@ -86,12 +87,13 @@ typedef union _znode_op {
void *ptr; /* Used for passing pointers from the compile to execution phase, currently used for traits */
} znode_op;
typedef struct _znode { /* used only during compilation */
typedef struct _znode { /* used only during compilation */
int op_type;
union {
znode_op op;
zval constant; /* replaced by literal/zv */
zend_op_array *op_array;
zend_ast *ast;
} u;
zend_uint EA; /* extended attributes */
} znode;
@@ -207,12 +209,14 @@ typedef struct _zend_try_catch_element {
/* disable inline caching */
#define ZEND_ACC_NEVER_CACHE 0x400000
#define ZEND_ACC_PASS_REST_BY_REFERENCE 0x1000000
#define ZEND_ACC_PASS_REST_PREFER_REF 0x2000000
#define ZEND_ACC_VARIADIC 0x1000000
#define ZEND_ACC_RETURN_REFERENCE 0x4000000
#define ZEND_ACC_DONE_PASS_TWO 0x8000000
/* function has arguments with type hinting */
#define ZEND_ACC_HAS_TYPE_HINTS 0x10000000
char *zend_visibility_string(zend_uint fn_flags);
@@ -234,12 +238,13 @@ typedef struct _zend_arg_info {
const char *class_name;
zend_uint class_name_len;
zend_uchar type_hint;
zend_uchar pass_by_reference;
zend_bool allow_null;
zend_bool pass_by_reference;
zend_bool is_variadic;
} zend_arg_info;
/* the following structure repeats the layout of zend_arg_info,
* but its fields have different meaning. It's used as the first element of
* but its fields have different meaning. It's used as the first element of
* arg_info array to define properties of internal functions.
*/
typedef struct _zend_internal_function_info {
@@ -249,7 +254,8 @@ typedef struct _zend_internal_function_info {
zend_uint required_num_args;
zend_uchar _type_hint;
zend_bool return_reference;
zend_bool pass_rest_by_reference;
zend_bool _allow_null;
zend_bool _is_variadic;
} zend_internal_function_info;
typedef struct _zend_compiled_variable {
@@ -261,7 +267,7 @@ typedef struct _zend_compiled_variable {
struct _zend_op_array {
/* Common elements */
zend_uchar type;
const char *function_name;
const char *function_name;
zend_class_entry *scope;
zend_uint fn_flags;
union _zend_function *prototype;
@@ -395,6 +401,7 @@ struct _zend_execute_data {
zend_class_entry *current_called_scope;
zval *current_this;
struct _zend_op *fast_ret; /* used by FAST_CALL/FAST_RET (finally keyword) */
zval *delayed_exception;
call_slot *call_slots;
call_slot *call;
};
@@ -437,8 +444,10 @@ ZEND_API char *zend_get_compiled_filename(TSRMLS_D);
ZEND_API int zend_get_compiled_lineno(TSRMLS_D);
ZEND_API size_t zend_get_scanned_file_offset(TSRMLS_D);
void zend_resolve_non_class_name(znode *element_name, zend_bool check_namespace TSRMLS_DC);
void zend_resolve_class_name(znode *class_name, ulong fetch_type, int check_ns_name TSRMLS_DC);
void zend_resolve_non_class_name(znode *element_name, zend_bool *check_namespace, zend_bool case_sensitive, HashTable *current_import_sub TSRMLS_DC);
void zend_resolve_function_name(znode *element_name, zend_bool *check_namespace TSRMLS_DC);
void zend_resolve_const_name(znode *element_name, zend_bool *check_namespace TSRMLS_DC);
void zend_resolve_class_name(znode *class_name TSRMLS_DC);
ZEND_API const char* zend_get_compiled_variable_name(const zend_op_array *op_array, zend_uint var, int* name_len);
#ifdef ZTS
@@ -500,7 +509,7 @@ void zend_do_add_variable(znode *result, const znode *op1, const znode *op2 TSRM
int zend_do_verify_access_types(const znode *current_access_type, const znode *new_modifier);
void zend_do_begin_function_declaration(znode *function_token, znode *function_name, int is_method, int return_reference, znode *fn_flags_znode TSRMLS_DC);
void zend_do_end_function_declaration(const znode *function_token TSRMLS_DC);
void zend_do_receive_arg(zend_uchar op, znode *varname, const znode *offset, const znode *initialization, znode *class_type, zend_bool pass_by_reference TSRMLS_DC);
void zend_do_receive_param(zend_uchar op, znode *varname, const znode *initialization, znode *class_type, zend_bool pass_by_reference, zend_bool is_variadic TSRMLS_DC);
int zend_do_begin_function_call(znode *function_name, zend_bool check_namespace TSRMLS_DC);
void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC);
void zend_do_clone(znode *result, const znode *expr TSRMLS_DC);
@@ -636,7 +645,11 @@ void zend_do_begin_namespace(const znode *name, zend_bool with_brackets TSRMLS_D
void zend_do_end_namespace(TSRMLS_D);
void zend_verify_namespace(TSRMLS_D);
void zend_do_use(znode *name, znode *new_name, int is_global TSRMLS_DC);
void zend_do_use_non_class(znode *ns_name, znode *new_name, int is_global, int is_function, zend_bool case_sensitive, HashTable *current_import_sub, HashTable *lookup_table TSRMLS_DC);
void zend_do_use_function(znode *name, znode *new_name, int is_global TSRMLS_DC);
void zend_do_use_const(znode *name, znode *new_name, int is_global TSRMLS_DC);
void zend_do_end_compilation(TSRMLS_D);
void zend_do_constant_expression(znode *result, zend_ast *ast TSRMLS_DC);
void zend_do_resolve_class_name(znode *result, znode *class_name, int is_static TSRMLS_DC);
@@ -674,7 +687,7 @@ void zend_class_add_ref(zend_class_entry **ce);
ZEND_API void zend_mangle_property_name(char **dest, int *dest_length, const char *src1, int src1_length, const char *src2, int src2_length, int internal);
#define zend_unmangle_property_name(mangled_property, mangled_property_len, class_name, prop_name) \
zend_unmangle_property_name_ex(mangled_property, mangled_property_len, class_name, prop_name, NULL)
zend_unmangle_property_name_ex(mangled_property, mangled_property_len, class_name, prop_name, NULL)
ZEND_API int zend_unmangle_property_name_ex(const char *mangled_property, int mangled_property_len, const char **class_name, const char **prop_name, int *prop_len);
#define ZEND_FUNCTION_DTOR (void (*)(void *)) zend_function_dtor
@@ -726,8 +739,8 @@ int zend_add_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC);
#define ZEND_FETCH_CLASS_DEFAULT 0
#define ZEND_FETCH_CLASS_SELF 1
#define ZEND_FETCH_CLASS_PARENT 2
#define ZEND_FETCH_CLASS_MAIN 3
#define ZEND_FETCH_CLASS_GLOBAL 4
#define ZEND_FETCH_CLASS_MAIN 3 /* unused */
#define ZEND_FETCH_CLASS_GLOBAL 4 /* unused */
#define ZEND_FETCH_CLASS_AUTO 5
#define ZEND_FETCH_CLASS_INTERFACE 6
#define ZEND_FETCH_CLASS_STATIC 7
@@ -817,21 +830,21 @@ int zend_add_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC);
#define ZEND_SEND_BY_REF 1
#define ZEND_SEND_PREFER_REF 2
#define CHECK_ARG_SEND_TYPE(zf, arg_num, m1, m2) \
((zf) && \
((((zend_function*)(zf))->common.arg_info && \
arg_num <= ((zend_function*)(zf))->common.num_args) ? \
(((zend_function *)(zf))->common.arg_info[arg_num-1].pass_by_reference & (m1)) : \
(((zend_function *)(zf))->common.fn_flags & (m2))))
#define CHECK_ARG_SEND_TYPE(zf, arg_num, m) \
((zf)->common.arg_info && \
(arg_num <= (zf)->common.num_args \
? ((zf)->common.arg_info[arg_num-1].pass_by_reference & (m)) \
: ((zf)->common.fn_flags & ZEND_ACC_VARIADIC) \
? ((zf)->common.arg_info[(zf)->common.num_args-1].pass_by_reference & (m)) : 0))
#define ARG_MUST_BE_SENT_BY_REF(zf, arg_num) \
CHECK_ARG_SEND_TYPE(zf, arg_num, ZEND_SEND_BY_REF, ZEND_ACC_PASS_REST_BY_REFERENCE)
CHECK_ARG_SEND_TYPE(zf, arg_num, ZEND_SEND_BY_REF)
#define ARG_SHOULD_BE_SENT_BY_REF(zf, arg_num) \
CHECK_ARG_SEND_TYPE(zf, arg_num, ZEND_SEND_BY_REF|ZEND_SEND_PREFER_REF, ZEND_ACC_PASS_REST_BY_REFERENCE|ZEND_ACC_PASS_REST_PREFER_REF)
CHECK_ARG_SEND_TYPE(zf, arg_num, ZEND_SEND_BY_REF|ZEND_SEND_PREFER_REF)
#define ARG_MAY_BE_SENT_BY_REF(zf, arg_num) \
CHECK_ARG_SEND_TYPE(zf, arg_num, ZEND_SEND_PREFER_REF, ZEND_ACC_PASS_REST_PREFER_REF)
CHECK_ARG_SEND_TYPE(zf, arg_num, ZEND_SEND_PREFER_REF)
#define ZEND_RETURN_VAL 0
#define ZEND_RETURN_REF 1
@@ -839,6 +852,7 @@ int zend_add_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC);
#define ZEND_RETURNS_FUNCTION 1<<0
#define ZEND_RETURNS_NEW 1<<1
#define ZEND_RETURNS_VALUE 1<<2
#define ZEND_FAST_RET_TO_CATCH 1
#define ZEND_FAST_RET_TO_FINALLY 2
+38 -56
View File
@@ -25,7 +25,7 @@
#include "zend_variables.h"
#include "zend_operators.h"
#include "zend_globals.h"
#include "zend_API.h"
void free_zend_constant(zend_constant *c)
{
@@ -38,9 +38,7 @@ void free_zend_constant(zend_constant *c)
void copy_zend_constant(zend_constant *c)
{
if (!IS_INTERNED(c->name)) {
c->name = zend_strndup(c->name, c->name_len - 1);
}
c->name = str_strndup(c->name, c->name_len - 1);
if (!(c->flags & CONST_PERSISTENT)) {
zval_copy_ctor(&c->value);
}
@@ -119,42 +117,12 @@ void zend_register_standard_constants(TSRMLS_D)
REGISTER_MAIN_LONG_CONSTANT("DEBUG_BACKTRACE_IGNORE_ARGS", DEBUG_BACKTRACE_IGNORE_ARGS, CONST_PERSISTENT | CONST_CS);
/* true/false constants */
{
zend_constant c;
c.flags = CONST_PERSISTENT | CONST_CT_SUBST;
c.module_number = 0;
c.name = zend_strndup(ZEND_STRL("TRUE"));
c.name_len = sizeof("TRUE");
c.value.value.lval = 1;
c.value.type = IS_BOOL;
zend_register_constant(&c TSRMLS_CC);
c.name = zend_strndup(ZEND_STRL("FALSE"));
c.name_len = sizeof("FALSE");
c.value.value.lval = 0;
c.value.type = IS_BOOL;
zend_register_constant(&c TSRMLS_CC);
c.name = zend_strndup(ZEND_STRL("NULL"));
c.name_len = sizeof("NULL");
c.value.type = IS_NULL;
zend_register_constant(&c TSRMLS_CC);
c.flags = CONST_PERSISTENT | CONST_CS;
c.name = zend_strndup(ZEND_STRL("ZEND_THREAD_SAFE"));
c.name_len = sizeof("ZEND_THREAD_SAFE");
c.value.value.lval = ZTS_V;
c.value.type = IS_BOOL;
zend_register_constant(&c TSRMLS_CC);
c.name = zend_strndup(ZEND_STRL("ZEND_DEBUG_BUILD"));
c.name_len = sizeof("ZEND_DEBUG_BUILD");
c.value.value.lval = ZEND_DEBUG;
c.value.type = IS_BOOL;
zend_register_constant(&c TSRMLS_CC);
REGISTER_MAIN_BOOL_CONSTANT("TRUE", 1, CONST_PERSISTENT | CONST_CT_SUBST);
REGISTER_MAIN_BOOL_CONSTANT("FALSE", 0, CONST_PERSISTENT | CONST_CT_SUBST);
REGISTER_MAIN_BOOL_CONSTANT("ZEND_THREAD_SAFE", ZTS_V, CONST_PERSISTENT | CONST_CS);
REGISTER_MAIN_BOOL_CONSTANT("ZEND_DEBUG_BUILD", ZEND_DEBUG, CONST_PERSISTENT | CONST_CS);
}
REGISTER_MAIN_NULL_CONSTANT("NULL", CONST_PERSISTENT | CONST_CT_SUBST);
}
@@ -175,13 +143,35 @@ void clean_non_persistent_constants(TSRMLS_D)
}
}
ZEND_API void zend_register_null_constant(const char *name, uint name_len, int flags, int module_number TSRMLS_DC)
{
zend_constant c;
ZVAL_NULL(&c.value);
c.flags = flags;
c.name = zend_strndup(name, name_len-1);
c.name_len = name_len;
c.module_number = module_number;
zend_register_constant(&c TSRMLS_CC);
}
ZEND_API void zend_register_bool_constant(const char *name, uint name_len, zend_bool bval, int flags, int module_number TSRMLS_DC)
{
zend_constant c;
ZVAL_BOOL(&c.value, bval);
c.flags = flags;
c.name = zend_strndup(name, name_len-1);
c.name_len = name_len;
c.module_number = module_number;
zend_register_constant(&c TSRMLS_CC);
}
ZEND_API void zend_register_long_constant(const char *name, uint name_len, long lval, int flags, int module_number TSRMLS_DC)
{
zend_constant c;
c.value.type = IS_LONG;
c.value.value.lval = lval;
ZVAL_LONG(&c.value, lval);
c.flags = flags;
c.name = zend_strndup(name, name_len-1);
c.name_len = name_len;
@@ -194,8 +184,7 @@ ZEND_API void zend_register_double_constant(const char *name, uint name_len, dou
{
zend_constant c;
c.value.type = IS_DOUBLE;
c.value.value.dval = dval;
ZVAL_DOUBLE(&c.value, dval);
c.flags = flags;
c.name = zend_strndup(name, name_len-1);
c.name_len = name_len;
@@ -208,9 +197,7 @@ ZEND_API void zend_register_stringl_constant(const char *name, uint name_len, ch
{
zend_constant c;
c.value.type = IS_STRING;
c.value.value.str.val = strval;
c.value.value.str.len = strlen;
ZVAL_STRINGL(&c.value, strval, strlen, 0);
c.flags = flags;
c.name = zend_strndup(name, name_len-1);
c.name_len = name_len;
@@ -485,7 +472,7 @@ ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC)
char *lowercase_name = NULL;
char *name;
int ret = SUCCESS;
ulong chash = 0;
ulong chash;
#if 0
printf("Registering constant for module %d\n", c->module_number);
@@ -497,23 +484,18 @@ ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC)
zend_str_tolower(lowercase_name, c->name_len-1);
lowercase_name = (char*)zend_new_interned_string(lowercase_name, c->name_len, 1 TSRMLS_CC);
name = lowercase_name;
chash = IS_INTERNED(lowercase_name) ? INTERNED_HASH(lowercase_name) : 0;
} else {
char *slash = strrchr(c->name, '\\');
if(slash) {
if (slash) {
lowercase_name = estrndup(c->name, c->name_len-1);
zend_str_tolower(lowercase_name, slash-c->name);
lowercase_name = (char*)zend_new_interned_string(lowercase_name, c->name_len, 1 TSRMLS_CC);
name = lowercase_name;
chash = IS_INTERNED(lowercase_name) ? INTERNED_HASH(lowercase_name) : 0;
} else {
name = c->name;
}
}
if (chash == 0) {
chash = zend_hash_func(name, c->name_len);
}
chash = str_hash(name, c->name_len-1);
/* Check if the user is trying to define the internal pseudo constant name __COMPILER_HALT_OFFSET__ */
if ((c->name_len == sizeof("__COMPILER_HALT_OFFSET__")
@@ -532,8 +514,8 @@ ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC)
}
ret = FAILURE;
}
if (lowercase_name && !IS_INTERNED(lowercase_name)) {
efree(lowercase_name);
if (lowercase_name) {
str_efree(lowercase_name);
}
return ret;
}
+8
View File
@@ -38,16 +38,22 @@ typedef struct _zend_constant {
int module_number;
} zend_constant;
#define REGISTER_NULL_CONSTANT(name, flags) zend_register_null_constant((name), sizeof(name), (flags), module_number TSRMLS_CC)
#define REGISTER_BOOL_CONSTANT(name, bval, flags) zend_register_bool_constant((name), sizeof(name), (bval), (flags), module_number TSRMLS_CC)
#define REGISTER_LONG_CONSTANT(name, lval, flags) zend_register_long_constant((name), sizeof(name), (lval), (flags), module_number TSRMLS_CC)
#define REGISTER_DOUBLE_CONSTANT(name, dval, flags) zend_register_double_constant((name), sizeof(name), (dval), (flags), module_number TSRMLS_CC)
#define REGISTER_STRING_CONSTANT(name, str, flags) zend_register_string_constant((name), sizeof(name), (str), (flags), module_number TSRMLS_CC)
#define REGISTER_STRINGL_CONSTANT(name, str, len, flags) zend_register_stringl_constant((name), sizeof(name), (str), (len), (flags), module_number TSRMLS_CC)
#define REGISTER_NS_NULL_CONSTANT(ns, name, flags) zend_register_null_constant(ZEND_NS_NAME(ns, name), sizeof(ZEND_NS_NAME(ns, name)), (flags), module_number TSRMLS_CC)
#define REGISTER_NS_BOOL_CONSTANT(ns, name, bval, flags) zend_register_bool_constant(ZEND_NS_NAME(ns, name), sizeof(ZEND_NS_NAME(ns, name)), (bval), (flags), module_number TSRMLS_CC)
#define REGISTER_NS_LONG_CONSTANT(ns, name, lval, flags) zend_register_long_constant(ZEND_NS_NAME(ns, name), sizeof(ZEND_NS_NAME(ns, name)), (lval), (flags), module_number TSRMLS_CC)
#define REGISTER_NS_DOUBLE_CONSTANT(ns, name, dval, flags) zend_register_double_constant(ZEND_NS_NAME(ns, name), sizeof(ZEND_NS_NAME(ns, name)), (dval), (flags), module_number TSRMLS_CC)
#define REGISTER_NS_STRING_CONSTANT(ns, name, str, flags) zend_register_string_constant(ZEND_NS_NAME(ns, name), sizeof(ZEND_NS_NAME(ns, name)), (str), (flags), module_number TSRMLS_CC)
#define REGISTER_NS_STRINGL_CONSTANT(ns, name, str, len, flags) zend_register_stringl_constant(ZEND_NS_NAME(ns, name), sizeof(ZEND_NS_NAME(ns, name)), (str), (len), (flags), module_number TSRMLS_CC)
#define REGISTER_MAIN_NULL_CONSTANT(name, flags) zend_register_null_constant((name), sizeof(name), (flags), 0 TSRMLS_CC)
#define REGISTER_MAIN_BOOL_CONSTANT(name, bval, flags) zend_register_bool_constant((name), sizeof(name), (bval), (flags), 0 TSRMLS_CC)
#define REGISTER_MAIN_LONG_CONSTANT(name, lval, flags) zend_register_long_constant((name), sizeof(name), (lval), (flags), 0 TSRMLS_CC)
#define REGISTER_MAIN_DOUBLE_CONSTANT(name, dval, flags) zend_register_double_constant((name), sizeof(name), (dval), (flags), 0 TSRMLS_CC)
#define REGISTER_MAIN_STRING_CONSTANT(name, str, flags) zend_register_string_constant((name), sizeof(name), (str), (flags), 0 TSRMLS_CC)
@@ -62,6 +68,8 @@ void zend_register_standard_constants(TSRMLS_D);
void clean_non_persistent_constants(TSRMLS_D);
ZEND_API int zend_get_constant(const char *name, uint name_len, zval *result TSRMLS_DC);
ZEND_API int zend_get_constant_ex(const char *name, uint name_len, zval *result, zend_class_entry *scope, ulong flags TSRMLS_DC);
ZEND_API void zend_register_bool_constant(const char *name, uint name_len, zend_bool bval, int flags, int module_number TSRMLS_DC);
ZEND_API void zend_register_null_constant(const char *name, uint name_len, int flags, int module_number TSRMLS_DC);
ZEND_API void zend_register_long_constant(const char *name, uint name_len, long lval, int flags, int module_number TSRMLS_DC);
ZEND_API void zend_register_double_constant(const char *name, uint name_len, double dval, int flags, int module_number TSRMLS_DC);
ZEND_API void zend_register_string_constant(const char *name, uint name_len, char *strval, int flags, int module_number TSRMLS_DC);
+86 -82
View File
@@ -40,7 +40,7 @@
#include "zend_dtrace.h"
/* Virtual current working directory support */
#include "tsrm_virtual_cwd.h"
#include "zend_virtual_cwd.h"
#define _CONST_CODE 0
#define _TMP_CODE 1
@@ -79,7 +79,6 @@ static zend_always_inline void zend_pzval_unlock_func(zval *z, zend_free_op *sho
if (unref && Z_ISREF_P(z) && Z_REFCOUNT_P(z) == 1) {
Z_UNSET_ISREF_P(z);
}
GC_ZVAL_CHECK_POSSIBLE_ROOT(z);
}
}
@@ -94,7 +93,8 @@ static zend_always_inline void zend_pzval_unlock_free_func(zval *z TSRMLS_DC)
}
#undef zval_ptr_dtor
#define zval_ptr_dtor(pzv) i_zval_ptr_dtor(*(pzv) ZEND_FILE_LINE_CC)
#define zval_ptr_dtor(pzv) i_zval_ptr_dtor(*(pzv) ZEND_FILE_LINE_CC TSRMLS_CC)
#define zval_ptr_dtor_nogc(pzv) i_zval_ptr_dtor_nogc(*(pzv) ZEND_FILE_LINE_CC TSRMLS_CC)
#define PZVAL_UNLOCK(z, f) zend_pzval_unlock_func(z, f, 1 TSRMLS_CC)
#define PZVAL_UNLOCK_EX(z, f, u) zend_pzval_unlock_func(z, f, u TSRMLS_CC)
@@ -102,16 +102,14 @@ static zend_always_inline void zend_pzval_unlock_free_func(zval *z TSRMLS_DC)
#define PZVAL_LOCK(z) Z_ADDREF_P((z))
#define SELECTIVE_PZVAL_LOCK(pzv, opline) if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(pzv); }
#define EXTRACT_ZVAL_PTR(t) do { \
temp_variable *__t = (t); \
if (__t->var.ptr_ptr) { \
__t->var.ptr = *__t->var.ptr_ptr; \
__t->var.ptr_ptr = &__t->var.ptr; \
if (!PZVAL_IS_REF(__t->var.ptr) && \
Z_REFCOUNT_P(__t->var.ptr) > 2) { \
SEPARATE_ZVAL(__t->var.ptr_ptr); \
} \
} \
#define EXTRACT_ZVAL_PTR(t) do { \
temp_variable *__t = (t); \
__t->var.ptr = *__t->var.ptr_ptr; \
__t->var.ptr_ptr = &__t->var.ptr; \
if (!PZVAL_IS_REF(__t->var.ptr) && \
Z_REFCOUNT_P(__t->var.ptr) > 2) { \
SEPARATE_ZVAL(__t->var.ptr_ptr); \
} \
} while (0)
#define AI_SET_PTR(t, val) do { \
@@ -125,18 +123,18 @@ static zend_always_inline void zend_pzval_unlock_free_func(zval *z TSRMLS_DC)
if ((zend_uintptr_t)should_free.var & 1L) { \
zval_dtor((zval*)((zend_uintptr_t)should_free.var & ~1L)); \
} else { \
zval_ptr_dtor(&should_free.var); \
zval_ptr_dtor_nogc(&should_free.var); \
} \
}
#define FREE_OP_IF_VAR(should_free) \
if (should_free.var != NULL && (((zend_uintptr_t)should_free.var & 1L) == 0)) { \
zval_ptr_dtor(&should_free.var); \
zval_ptr_dtor_nogc(&should_free.var); \
}
#define FREE_OP_VAR_PTR(should_free) \
if (should_free.var) { \
zval_ptr_dtor(&should_free.var); \
zval_ptr_dtor_nogc(&should_free.var); \
}
#define TMP_FREE(z) (zval*)(((zend_uintptr_t)(z)) | 1L)
@@ -183,8 +181,7 @@ static zend_always_inline zval *_get_zval_ptr_var(zend_uint var, const zend_exec
{
zval *ptr = EX_T(var).var.ptr;
PZVAL_UNLOCK(ptr, should_free);
return ptr;
return should_free->var = ptr;
}
static zend_never_inline zval **_get_zval_cv_lookup(zval ***ptr, zend_uint var, int type TSRMLS_DC)
@@ -386,6 +383,19 @@ static zend_always_inline zval **_get_zval_ptr_ptr_var(zend_uint var, const zend
return ptr_ptr;
}
static zend_always_inline zval **_get_zval_ptr_ptr_var_fast(zend_uint var, const zend_execute_data *execute_data, zend_free_op *should_free TSRMLS_DC)
{
zval** ptr_ptr = EX_T(var).var.ptr_ptr;
if (EXPECTED(ptr_ptr != NULL)) {
should_free->var = *ptr_ptr;
} else {
/* string offset */
should_free->var = EX_T(var).str_offset.str;
}
return ptr_ptr;
}
static zend_always_inline zval **_get_zval_ptr_ptr_cv(zend_uint var, int type TSRMLS_DC)
{
zval ***ptr = EX_CV_NUM(EG(current_execute_data), var);
@@ -604,12 +614,17 @@ static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zva
char *need_msg;
zend_class_entry *ce;
if (!zf->common.arg_info
|| arg_num>zf->common.num_args) {
if (!zf->common.arg_info) {
return 1;
}
cur_arg_info = &zf->common.arg_info[arg_num-1];
if (arg_num <= zf->common.num_args) {
cur_arg_info = &zf->common.arg_info[arg_num-1];
} else if (zf->common.fn_flags & ZEND_ACC_VARIADIC) {
cur_arg_info = &zf->common.arg_info[zf->common.num_args-1];
} else {
return 1;
}
if (cur_arg_info->class_name) {
const char *class_name;
@@ -755,32 +770,21 @@ static inline void zend_assign_to_object(zval **retval, zval **object_ptr, zval
static inline int zend_assign_to_string_offset(const temp_variable *T, const zval *value, int value_type TSRMLS_DC)
{
if (Z_TYPE_P(T->str_offset.str) == IS_STRING) {
if (((int)T->str_offset.offset < 0)) {
zend_error(E_WARNING, "Illegal string offset: %d", T->str_offset.offset);
zval *str = T->str_offset.str;
zend_uint offset = T->str_offset.offset;
if (Z_TYPE_P(str) == IS_STRING) {
if ((int)offset < 0) {
zend_error(E_WARNING, "Illegal string offset: %d", offset);
return 0;
}
if (T->str_offset.offset >= Z_STRLEN_P(T->str_offset.str)) {
if (IS_INTERNED(Z_STRVAL_P(T->str_offset.str))) {
char *tmp = (char *) emalloc(T->str_offset.offset+1+1);
memcpy(tmp, Z_STRVAL_P(T->str_offset.str), Z_STRLEN_P(T->str_offset.str)+1);
Z_STRVAL_P(T->str_offset.str) = tmp;
} else {
Z_STRVAL_P(T->str_offset.str) = (char *) erealloc(Z_STRVAL_P(T->str_offset.str), T->str_offset.offset+1+1);
}
memset(Z_STRVAL_P(T->str_offset.str) + Z_STRLEN_P(T->str_offset.str),
' ',
T->str_offset.offset - Z_STRLEN_P(T->str_offset.str));
Z_STRVAL_P(T->str_offset.str)[T->str_offset.offset+1] = 0;
Z_STRLEN_P(T->str_offset.str) = T->str_offset.offset+1;
} else if (IS_INTERNED(Z_STRVAL_P(T->str_offset.str))) {
char *tmp = (char *) emalloc(Z_STRLEN_P(T->str_offset.str) + 1);
memcpy(tmp, Z_STRVAL_P(T->str_offset.str), Z_STRLEN_P(T->str_offset.str) + 1);
Z_STRVAL_P(T->str_offset.str) = tmp;
if (offset >= Z_STRLEN_P(str)) {
Z_STRVAL_P(str) = str_erealloc(Z_STRVAL_P(str), offset+1+1);
memset(Z_STRVAL_P(str) + Z_STRLEN_P(str), ' ', offset - Z_STRLEN_P(str));
Z_STRVAL_P(str)[offset+1] = 0;
Z_STRLEN_P(str) = offset+1;
} else if (IS_INTERNED(Z_STRVAL_P(str))) {
Z_STRVAL_P(str) = estrndup(Z_STRVAL_P(str), Z_STRLEN_P(str));
}
if (Z_TYPE_P(value) != IS_STRING) {
@@ -791,15 +795,15 @@ static inline int zend_assign_to_string_offset(const temp_variable *T, const zva
zval_copy_ctor(&tmp);
}
convert_to_string(&tmp);
Z_STRVAL_P(T->str_offset.str)[T->str_offset.offset] = Z_STRVAL(tmp)[0];
STR_FREE(Z_STRVAL(tmp));
Z_STRVAL_P(str)[offset] = Z_STRVAL(tmp)[0];
str_efree(Z_STRVAL(tmp));
} else {
Z_STRVAL_P(T->str_offset.str)[T->str_offset.offset] = Z_STRVAL_P(value)[0];
Z_STRVAL_P(str)[offset] = Z_STRVAL_P(value)[0];
if (value_type == IS_TMP_VAR) {
/* we can safely free final_value here
* because separation is done only
* in case value_type == IS_VAR */
STR_FREE(Z_STRVAL_P(value));
str_efree(Z_STRVAL_P(value));
}
}
/*
@@ -909,7 +913,7 @@ static inline zval* zend_assign_to_variable(zval **variable_ptr_ptr, zval *value
} else { /* we need to split */
Z_DELREF_P(variable_ptr);
GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr);
if (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) {
if (PZVAL_IS_REF(value)) {
ALLOC_ZVAL(variable_ptr);
*variable_ptr_ptr = variable_ptr;
INIT_PZVAL_COPY(variable_ptr, value);
@@ -918,7 +922,6 @@ static inline zval* zend_assign_to_variable(zval **variable_ptr_ptr, zval *value
} else {
*variable_ptr_ptr = value;
Z_ADDREF_P(value);
Z_UNSET_ISREF_P(value);
return value;
}
}
@@ -1013,11 +1016,7 @@ static inline zval **zend_fetch_dimension_address_inner(HashTable *ht, const zva
hval = Z_HASH_P(dim);
} else {
ZEND_HANDLE_NUMERIC_EX(offset_key, offset_key_length+1, hval, goto num_index);
if (IS_INTERNED(offset_key)) {
hval = INTERNED_HASH(offset_key);
} else {
hval = zend_hash_func(offset_key, offset_key_length+1);
}
hval = str_hash(offset_key, offset_key_length);
}
fetch_string_dim:
if (zend_hash_quick_find(ht, offset_key, offset_key_length+1, hval, (void **) &retval) == FAILURE) {
@@ -1214,12 +1213,12 @@ convert_to_array:
zend_error(E_NOTICE, "Indirect modification of overloaded element of %s has no effect", ce->name);
}
}
retval = &overloaded_result;
AI_SET_PTR(result, overloaded_result);
PZVAL_LOCK(overloaded_result);
} else {
retval = &EG(error_zval_ptr);
result->var.ptr_ptr = &EG(error_zval_ptr);
PZVAL_LOCK(EG(error_zval_ptr));
}
AI_SET_PTR(result, *retval);
PZVAL_LOCK(*retval);
if (dim_type == IS_TMP_VAR) {
zval_ptr_dtor(&dim);
}
@@ -1236,8 +1235,8 @@ convert_to_array:
default:
if (type == BP_VAR_UNSET) {
zend_error(E_WARNING, "Cannot unset offset in a non-array variable");
AI_SET_PTR(result, &EG(uninitialized_zval));
PZVAL_LOCK(&EG(uninitialized_zval));
result->var.ptr_ptr = &EG(uninitialized_zval_ptr);
PZVAL_LOCK(EG(uninitialized_zval_ptr));
} else {
zend_error(E_WARNING, "Cannot use a scalar value as an array");
result->var.ptr_ptr = &EG(error_zval_ptr);
@@ -1255,12 +1254,12 @@ static void zend_fetch_dimension_address_read(temp_variable *result, zval *conta
case IS_ARRAY:
retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type TSRMLS_CC);
AI_SET_PTR(result, *retval);
result->var.ptr = *retval;
PZVAL_LOCK(*retval);
return;
case IS_NULL:
AI_SET_PTR(result, &EG(uninitialized_zval));
result->var.ptr = &EG(uninitialized_zval);
PZVAL_LOCK(&EG(uninitialized_zval));
return;
@@ -1313,7 +1312,7 @@ static void zend_fetch_dimension_address_read(temp_variable *result, zval *conta
Z_STRVAL_P(ptr)[1] = 0;
Z_STRLEN_P(ptr) = 1;
}
AI_SET_PTR(result, ptr);
result->var.ptr = ptr;
return;
}
break;
@@ -1331,12 +1330,14 @@ static void zend_fetch_dimension_address_read(temp_variable *result, zval *conta
}
overloaded_result = Z_OBJ_HT_P(container)->read_dimension(container, dim, type TSRMLS_CC);
if (overloaded_result) {
AI_SET_PTR(result, overloaded_result);
PZVAL_LOCK(overloaded_result);
} else if (result) {
AI_SET_PTR(result, &EG(uninitialized_zval));
PZVAL_LOCK(&EG(uninitialized_zval));
if (result) {
if (overloaded_result) {
result->var.ptr = overloaded_result;
PZVAL_LOCK(overloaded_result);
} else {
result->var.ptr = &EG(uninitialized_zval);
PZVAL_LOCK(&EG(uninitialized_zval));
}
}
if (dim_type == IS_TMP_VAR) {
zval_ptr_dtor(&dim);
@@ -1345,7 +1346,7 @@ static void zend_fetch_dimension_address_read(temp_variable *result, zval *conta
return;
default:
AI_SET_PTR(result, &EG(uninitialized_zval));
result->var.ptr = &EG(uninitialized_zval);
PZVAL_LOCK(&EG(uninitialized_zval));
return;
}
@@ -1475,15 +1476,17 @@ ZEND_API opcode_handler_t *zend_opcode_handlers;
ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, zend_fcall_info *fci, int return_value_used TSRMLS_DC)
{
if(fci != NULL) {
((zend_internal_function *) execute_data_ptr->function_state.function)->handler(fci->param_count,
*fci->retval_ptr_ptr, fci->retval_ptr_ptr, fci->object_ptr, 1 TSRMLS_CC);
if (fci != NULL) {
execute_data_ptr->function_state.function->internal_function.handler(
fci->param_count, *fci->retval_ptr_ptr, fci->retval_ptr_ptr,
fci->object_ptr, 1 TSRMLS_CC
);
} else {
zval **return_value_ptr = &EX_TMP_VAR(execute_data_ptr, execute_data_ptr->opline->result.var)->var.ptr;
((zend_internal_function *) execute_data_ptr->function_state.function)->handler(execute_data_ptr->opline->extended_value, *return_value_ptr,
(execute_data_ptr->function_state.function->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)?return_value_ptr:NULL,
execute_data_ptr->object, return_value_used TSRMLS_CC);
execute_data_ptr->function_state.function->internal_function.handler(
execute_data_ptr->opline->extended_value, *return_value_ptr, return_value_ptr,
execute_data_ptr->object, return_value_used TSRMLS_CC
);
}
}
@@ -1501,7 +1504,7 @@ void zend_clean_and_cache_symbol_table(HashTable *symbol_table TSRMLS_DC) /* {{{
}
/* }}} */
static zend_always_inline void i_free_compiled_variables(zend_execute_data *execute_data) /* {{{ */
static zend_always_inline void i_free_compiled_variables(zend_execute_data *execute_data TSRMLS_DC) /* {{{ */
{
zval ***cv = EX_CV_NUM(execute_data, 0);
zval ***end = cv + EX(op_array)->last_var;
@@ -1514,9 +1517,9 @@ static zend_always_inline void i_free_compiled_variables(zend_execute_data *exec
}
/* }}} */
void zend_free_compiled_variables(zend_execute_data *execute_data) /* {{{ */
void zend_free_compiled_variables(zend_execute_data *execute_data TSRMLS_DC) /* {{{ */
{
i_free_compiled_variables(execute_data);
i_free_compiled_variables(execute_data TSRMLS_CC);
}
/* }}} */
@@ -1647,6 +1650,7 @@ static zend_always_inline zend_execute_data *i_create_execute_data_from_op_array
EX(call) = NULL;
EG(current_execute_data) = execute_data;
EX(nested) = nested;
EX(delayed_exception) = NULL;
if (!op_array->run_time_cache && op_array->last_cache_slot) {
op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*));
@@ -1674,7 +1678,7 @@ static zend_always_inline zend_execute_data *i_create_execute_data_from_op_array
}
/* }}} */
zend_execute_data *zend_create_execute_data_from_op_array(zend_op_array *op_array, zend_bool nested TSRMLS_DC) /* {{{ */
ZEND_API zend_execute_data *zend_create_execute_data_from_op_array(zend_op_array *op_array, zend_bool nested TSRMLS_DC) /* {{{ */
{
return i_create_execute_data_from_op_array(op_array, nested TSRMLS_CC);
}

Some files were not shown because too many files have changed in this diff Show More