mirror of
https://github.com/php/php-src.git
synced 2024-09-21 09:57:23 +00:00
Merge in master
This commit is contained in:
commit
9109e48749
@ -401,8 +401,8 @@ MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: json
|
||||
PRIMARY MAINTAINER: Unknown
|
||||
MAINTENANCE: Odd fixes
|
||||
PRIMARY MAINTAINER: Jakub Zelenka <bukka@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.2
|
||||
-------------------------------------------------------------------------------
|
||||
|
14
NEWS
14
NEWS
@ -8,9 +8,9 @@
|
||||
. Update the MIME type list from the one shipped by Apache HTTPD. (Adam)
|
||||
|
||||
- Core:
|
||||
. Fixed #68933 (Invalid read of size 8 in zend_std_read_property).
|
||||
. Fixed bug #68933 (Invalid read of size 8 in zend_std_read_property).
|
||||
(Laruence, arjen at react dot com)
|
||||
. Fixed #68868 (Segfault in clean_non_persistent_constants() in SugarCRM
|
||||
. Fixed bug #68868 (Segfault in clean_non_persistent_constants() in SugarCRM
|
||||
6.5.20). (Laruence)
|
||||
. Fixed bug #68104 (Segfault while pre-evaluating a disabled function).
|
||||
(Laruence)
|
||||
@ -19,7 +19,7 @@
|
||||
. Added PHP_INT_MIN constant. (Andrea)
|
||||
. Added Closure::call() method. (Andrea)
|
||||
. Implemented FR #38409 (parse_ini_file() looses the type of booleans). (Tjerk)
|
||||
. Fixed #67959 (Segfault when calling phpversion('spl')). (Florian)
|
||||
. Fixed bug #67959 (Segfault when calling phpversion('spl')). (Florian)
|
||||
. Implemented the RFC `Catchable "Call to a member function bar() on a
|
||||
non-object"`. (Timm)
|
||||
. Added options parameter for unserialize allowing to specify acceptable
|
||||
@ -45,6 +45,8 @@
|
||||
. Invalid octal literals in source code now produce compile errors, fixes PHPSadness #31. (Andrea)
|
||||
. Removed dl() function on fpm-fcgi. (Nikita)
|
||||
. Removed support for hexadecimal numeric strings. (Nikita)
|
||||
. Removed obsolete extensions and SAPIs. See the full list in UPGRADING. (Anatol)
|
||||
. Added NULL byte protection to exec, system and passthru. (Yasuo)
|
||||
|
||||
- Curl:
|
||||
. Fixed bug #68937 (Segfault in curl_multi_exec). (Laruence)
|
||||
@ -94,7 +96,7 @@
|
||||
+ Opcache). (Laruence)
|
||||
|
||||
- OpenSSL:
|
||||
. Fix bug #61285, #68329, #68046, #41631: encrypted streams don't observe
|
||||
. Fixed bug #61285, #68329, #68046, #41631: encrypted streams don't observe
|
||||
socket timeouts (Brad Broerman)
|
||||
|
||||
- pcntl:
|
||||
@ -131,12 +133,12 @@
|
||||
. Fixed bug #68479 (Added escape parameter to SplFileObject::fputcsv). (Salathe)
|
||||
|
||||
- Sqlite3:
|
||||
. Fix bug #68260 (SQLite3Result::fetchArray declares wrong
|
||||
. Fixed bug #68260 (SQLite3Result::fetchArray declares wrong
|
||||
required_num_args). (Julien)
|
||||
|
||||
- Standard:
|
||||
. Removed call_user_method() and call_user_method_array() functions. (Kalle)
|
||||
. Fix user session handlers (See rfc:session.user.return-value). (Sara)
|
||||
. Fixed user session handlers (See rfc:session.user.return-value). (Sara)
|
||||
. Added intdiv() function. (Andrea)
|
||||
. Improved precision of log() function for base 2 and 10. (Marc Bennewitz)
|
||||
. Remove string category support in setlocale(). (Nikita)
|
||||
|
16
TSRM/TSRM.h
16
TSRM/TSRM.h
@ -168,9 +168,13 @@ TSRM_API void *tsrm_get_ls_cache(void);
|
||||
#define TSRMG(id, type, element) (((type) (*((void ***) tsrm_get_ls_cache()))[TSRM_UNSHUFFLE_RSRC_ID(id)])->element)
|
||||
|
||||
#define TSRMG_STATIC(id, type, element) (((type) (*((void ***) TSRMLS_CACHE))[TSRM_UNSHUFFLE_RSRC_ID(id)])->element)
|
||||
#define TSRMLS_CACHE_EXTERN extern TSRM_TLS void *TSRMLS_CACHE
|
||||
#define TSRMLS_CACHE_DEFINE TSRM_TLS void *TSRMLS_CACHE = NULL
|
||||
#define TSRMLS_CACHE_UPDATE if (!TSRMLS_CACHE) TSRMLS_CACHE = tsrm_get_ls_cache()
|
||||
#define TSRMLS_CACHE_EXTERN() extern TSRM_TLS void *TSRMLS_CACHE
|
||||
#define TSRMLS_CACHE_DEFINE() TSRM_TLS void *TSRMLS_CACHE = NULL
|
||||
#if ZEND_DEBUG
|
||||
#define TSRMLS_CACHE_UPDATE() TSRMLS_CACHE = tsrm_get_ls_cache()
|
||||
#else
|
||||
#define TSRMLS_CACHE_UPDATE() if (!TSRMLS_CACHE) TSRMLS_CACHE = tsrm_get_ls_cache()
|
||||
#endif
|
||||
#define TSRMLS_CACHE _tsrm_ls_cache
|
||||
|
||||
/* BC only */
|
||||
@ -191,9 +195,9 @@ TSRM_API void *tsrm_get_ls_cache(void);
|
||||
#define TSRMLS_SET_CTX(ctx)
|
||||
|
||||
#define TSRMG_STATIC(id, type, element)
|
||||
#define TSRMLS_CACHE_EXTERN
|
||||
#define TSRMLS_CACHE_DEFINE
|
||||
#define TSRMLS_CACHE_UPDATE
|
||||
#define TSRMLS_CACHE_EXTERN()
|
||||
#define TSRMLS_CACHE_DEFINE()
|
||||
#define TSRMLS_CACHE_UPDATE()
|
||||
#define TSRMLS_CACHE
|
||||
|
||||
/* BC only */
|
||||
|
@ -43,7 +43,7 @@ static tsrm_win32_globals win32_globals;
|
||||
static void tsrm_win32_ctor(tsrm_win32_globals *globals)
|
||||
{
|
||||
#ifdef ZTS
|
||||
TSRMLS_CACHE_UPDATE;
|
||||
TSRMLS_CACHE_UPDATE();
|
||||
#endif
|
||||
globals->process = NULL;
|
||||
globals->shm = NULL;
|
||||
|
@ -72,7 +72,7 @@ typedef struct {
|
||||
|
||||
#ifdef ZTS
|
||||
# define TWG(v) TSRMG_STATIC(win32_globals_id, tsrm_win32_globals *, v)
|
||||
TSRMLS_CACHE_EXTERN;
|
||||
TSRMLS_CACHE_EXTERN();
|
||||
#else
|
||||
# define TWG(v) (win32_globals.v)
|
||||
#endif
|
||||
|
376
UPGRADING
376
UPGRADING
@ -9,7 +9,7 @@ PHP X.Y UPGRADE NOTES
|
||||
5. Changed Functions
|
||||
6. New Functions
|
||||
7. New Classes and Interfaces
|
||||
8. Removed Extensions
|
||||
8. Removed Extensions and SAPIs
|
||||
9. Other Changes to Extensions
|
||||
10. New Global Constants
|
||||
11. Changes to INI File Handling
|
||||
@ -21,58 +21,329 @@ PHP X.Y UPGRADE NOTES
|
||||
1. Backward Incompatible Changes
|
||||
========================================
|
||||
|
||||
- Core
|
||||
. list() now always supports ArrayAccess and never supports strings.
|
||||
Previously both were accepted in some situations and not in others.
|
||||
(RFC: https://wiki.php.net/rfc/fix_list_behavior_inconsistency)
|
||||
. Bitwise shifts by negative numbers of bits are disallowed (throws E_WARNING
|
||||
and gives FALSE, like a division by zero).
|
||||
. Left bitwise shifts by a number of bits beyond the bit width of an integer
|
||||
will always result in 0, even on CPUs which wrap around.
|
||||
. Right bitwise shifts by a number of bits beyond the bit width of an integer
|
||||
will always result in 0 or -1 (depending on sign), even on CPUs which wrap
|
||||
around.
|
||||
Language changes
|
||||
================
|
||||
|
||||
Changes to variable handling
|
||||
----------------------------
|
||||
|
||||
* Indirect variable, property and method references are now interpreted with
|
||||
left-to-right semantics. Some examples:
|
||||
|
||||
$$foo['bar']['baz'] // interpreted as ($$foo)['bar']['baz']
|
||||
$foo->$bar['baz'] // interpreted as ($foo->$bar)['baz']
|
||||
$foo->$bar['baz']() // interpreted as ($foo->$bar)['baz']()
|
||||
Foo::$bar['baz']() // interpreted as (Foo::$bar)['baz']()
|
||||
|
||||
To restore the previous behavior add explicit curly braces:
|
||||
|
||||
${$foo['bar']['baz']}
|
||||
$foo->{$bar['baz']}
|
||||
$foo->{$bar['baz']}()
|
||||
Foo::{$bar['baz']}()
|
||||
|
||||
* The global keyword now only accepts simple variables. Instead of
|
||||
|
||||
global $$foo->bar;
|
||||
|
||||
it is now required to write the following:
|
||||
|
||||
global ${$foo->bar};
|
||||
|
||||
* Parentheses around variables or function calls no longer have any influence
|
||||
on behavior. For example the following code, where the result of a function
|
||||
call is passed to a by-reference function
|
||||
|
||||
function getArray() { return [1, 2, 3]; }
|
||||
|
||||
$last = array_pop(getArray());
|
||||
// Strict Standards: Only variables should be passed by reference
|
||||
$last = array_pop((getArray()));
|
||||
// Strict Standards: Only variables should be passed by reference
|
||||
|
||||
will now throw a strict standards error irregardless of whether parentheses
|
||||
are used. Previously no notice was generated in the second case.
|
||||
|
||||
* Array elements or object properties that are automatically created during
|
||||
by-reference assignments will now result in a different order. For example
|
||||
|
||||
$array = [];
|
||||
$array["a"] =& $array["b"];
|
||||
$array["b"] = 1;
|
||||
var_dump($array);
|
||||
|
||||
now results in the array ["a" => 1, "b" => 1], while previously the result
|
||||
was ["b" => 1, "a" => 1];
|
||||
|
||||
Relevant RFCs:
|
||||
* https://wiki.php.net/rfc/uniform_variable_syntax
|
||||
* https://wiki.php.net/rfc/abstract_syntax_tree
|
||||
|
||||
Changes to list()
|
||||
-----------------
|
||||
|
||||
* list() will no longer assign variables in reverse order. For example
|
||||
|
||||
list($array[], $array[], $array[]) = [1, 2, 3];
|
||||
var_dump($array);
|
||||
|
||||
will now result in $array == [1, 2, 3] rather than [3, 2, 1]. Note that only
|
||||
the **order** of the assignments changed, but the assigned values stay the
|
||||
same. E.g. a normal usage like
|
||||
|
||||
list($a, $b, $c) = [1, 2, 3];
|
||||
// $a = 1; $b = 2; $c = 3;
|
||||
|
||||
will retain its current behavior.
|
||||
|
||||
* Empty list() assignments are no longer allowed. As such all of the following
|
||||
are invalid:
|
||||
|
||||
list() = $a;
|
||||
list(,,) = $a;
|
||||
list($x, list(), $y) = $a;
|
||||
|
||||
* list() no longer supports unpacking strings (while previously this was only
|
||||
supported in some cases). The code
|
||||
|
||||
$string = "xy";
|
||||
list($x, $y) = $string;
|
||||
|
||||
will now result in $x == null and $y == null (without notices) instead of
|
||||
$x == "x" and $y == "y". Furthermore list() is now always guaranteed to
|
||||
work with objects implementing ArrayAccess, e.g.
|
||||
|
||||
list($a, $b) = (object) new ArrayObject([0, 1]);
|
||||
|
||||
will now result in $a == 0 and $b == 1. Previously both $a and $b were null.
|
||||
|
||||
Relevant RFCs:
|
||||
* https://wiki.php.net/rfc/abstract_syntax_tree#changes_to_list
|
||||
* https://wiki.php.net/rfc/fix_list_behavior_inconsistency
|
||||
|
||||
Changes to foreach
|
||||
------------------
|
||||
|
||||
* Iteration with foreach() no longer has any effect on the internal array
|
||||
pointer, which can be accessed through the current()/next()/etc family of
|
||||
functions. For example
|
||||
|
||||
$array = [0, 1, 2];
|
||||
foreach ($array as &$val) {
|
||||
var_dump(current($array));
|
||||
}
|
||||
|
||||
will now print the value int(0) three times. Previously the output was int(1),
|
||||
int(2) and bool(false).
|
||||
|
||||
* When iterating arrays by-value, foreach will now always operate on a copy of
|
||||
the array, as such changes to the array during iteration will not influence
|
||||
iteration behavior. For example
|
||||
|
||||
$array = [0, 1, 2];
|
||||
$ref =& $array; // Necessary to trigger the old behavior
|
||||
foreach ($array as $val) {
|
||||
var_dump($val);
|
||||
unset($array[1]);
|
||||
}
|
||||
|
||||
will now print all three elements (0 1 2), while previously the second element
|
||||
1 was skipped (0 2).
|
||||
|
||||
* When iterating arrays by-reference, modifications to the array will continue
|
||||
to influence the iteration. However PHP will now do a better job of
|
||||
maintaining a correct position in a number of cases. E.g. appending to an
|
||||
array during by-reference iteration
|
||||
|
||||
$array = [0];
|
||||
foreach ($array as &$val) {
|
||||
var_dump($val);
|
||||
$array[1] = 1;
|
||||
}
|
||||
|
||||
will now iterate over the appended element as well. As such the output of this
|
||||
example will now be "int(0) int(1)", while previously it was only "int(0)".
|
||||
|
||||
* Iteration of plain (non-Traversable) objects by-value or by-reference will
|
||||
behave like by-reference iteration of arrays. This matches the previous
|
||||
behavior apart from the more accurate position management mentioned in the
|
||||
previous point.
|
||||
|
||||
* Iteration of Traversable objects remains unchanged.
|
||||
|
||||
Relevant RFC: https://wiki.php.net/rfc/php7_foreach
|
||||
|
||||
Changes to parameter handling
|
||||
-----------------------------
|
||||
|
||||
* It is no longer possible to define two function parameters with the same name.
|
||||
For example, the following method will trigger a compile-time error:
|
||||
|
||||
public function foo($a, $b, $unused, $unused) {
|
||||
// ...
|
||||
}
|
||||
|
||||
Code like this should be changed to use distinct parameter names, for example:
|
||||
|
||||
public function foo($a, $b, $unused1, $unused2) {
|
||||
// ...
|
||||
}
|
||||
|
||||
* The func_get_arg() and func_get_args() functions will no longer return the
|
||||
original value that was passed to a parameter and will instead provide the
|
||||
current value (which might have been modified). For example
|
||||
|
||||
function foo($x) {
|
||||
$x++;
|
||||
var_dump(func_get_arg(0));
|
||||
}
|
||||
foo(1);
|
||||
|
||||
will now print "2" instead of "1". This code should be changed to either
|
||||
perform modifications only after calling func_get_arg(s)
|
||||
|
||||
function foo($x) {
|
||||
var_dump(func_get_arg(0));
|
||||
$x++;
|
||||
}
|
||||
|
||||
or avoid modifying the parameters altogether:
|
||||
|
||||
function foo($x) {
|
||||
$newX = $x + 1;
|
||||
var_dump(func_get_arg(0));
|
||||
}
|
||||
|
||||
* Similarly exception backtraces will no longer display the original value that
|
||||
was passed to a function and show the modified value instead. For example
|
||||
|
||||
function foo($x) {
|
||||
$x = 42;
|
||||
throw new Exception;
|
||||
}
|
||||
foo("string");
|
||||
|
||||
will now result in the stack trace
|
||||
|
||||
Stack trace:
|
||||
#0 file.php(4): foo(42)
|
||||
#1 {main}
|
||||
|
||||
while previously it was:
|
||||
|
||||
Stack trace:
|
||||
#0 file.php(4): foo('string')
|
||||
#1 {main}
|
||||
|
||||
While this should not impact runtime behavior of your code, it is worthwhile
|
||||
to be aware of this difference for debugging purposes.
|
||||
|
||||
The same limitation also applies to debug_backtrace() and other functions
|
||||
inspecting function arguments.
|
||||
|
||||
Relevant RFC: https://wiki.php.net/phpng
|
||||
|
||||
Changes to integer handling
|
||||
---------------------------
|
||||
|
||||
* Invalid octal literals (containing digits larger than 7) now produce compile
|
||||
errors. For example, the following is no longer valid:
|
||||
|
||||
$i = 0781; // 8 is not a valid octal digit!
|
||||
|
||||
Previously the invalid digits (and any following valid digits) were simply
|
||||
ignored. As such $i previously held the value 7, because the last two digits
|
||||
were silently discarded.
|
||||
|
||||
* Bitwise shifts by negative numbers will now throw a warning and return false:
|
||||
|
||||
var_dump(1 >> -1); // bool(false)
|
||||
// Warning: Bit shift by negative number
|
||||
|
||||
* Left bitwise shifts by a number of bits beyond the bit width of an integer
|
||||
will always result in 0:
|
||||
|
||||
var_dump(1 << 64); // int(0)
|
||||
|
||||
Previously the behavior of this code was dependent on the used CPU
|
||||
architecture. For example on x86 (including x86-64) the result was int(1),
|
||||
because the shift operand was wrapped.
|
||||
|
||||
* Similarly right bitwise shifts by a number of bits beyond the bit width of an
|
||||
integer will always result in 0 or -1 (depending on sign):
|
||||
|
||||
var_dump(1 >> 64); // int(0)
|
||||
var_dump(-1 >> 64); // int(-1)
|
||||
|
||||
Relevant RFC: https://wiki.php.net/rfc/integer_semantics
|
||||
|
||||
Changes to string handling
|
||||
--------------------------
|
||||
|
||||
* Strings that contain hexadecimal numbers are no longer considered to be
|
||||
numeric and don't receive special treatment anymore. Some examples of the
|
||||
new behavior:
|
||||
|
||||
var_dump("0x123" == "291"); // bool(false) (previously true)
|
||||
var_dump(is_numeric("0x123")); // bool(false) (previously true)
|
||||
var_dump("0xe" + "0x1"); // int(0) (previously 16)
|
||||
|
||||
var_dump(substr("foo", "0x1")); // string(3) "foo" (previously "oo")
|
||||
// Notice: A non well formed numeric value encountered
|
||||
|
||||
filter_var() can be used to check if a string contains a hexadecimal number
|
||||
or convert such a string into an integer:
|
||||
|
||||
$str = "0xffff";
|
||||
$int = filter_var($str, FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX);
|
||||
if (false === $int) {
|
||||
throw new Exception("Invalid integer!");
|
||||
}
|
||||
var_dump($num); // int(65535)
|
||||
|
||||
* Due to the addition of the Unicode Codepoint Escape Syntax for double-quoted
|
||||
strings and heredocs, "\u{" followed by an invalid sequence will now result in
|
||||
an error:
|
||||
|
||||
$str = "\u{xyz}"; // Fatal error: Invalid UTF-8 codepoint escape sequence
|
||||
|
||||
To avoid this the leading backslash should be escaped:
|
||||
|
||||
$str = "\\u{xyz}"; // Works fine
|
||||
|
||||
However, "\u" without a following { is unaffected. As such the following code
|
||||
won't error and will work the same as before:
|
||||
|
||||
$str = "\u202e"; // Works fine
|
||||
|
||||
Relevant RFCs:
|
||||
* https://wiki.php.net/rfc/remove_hex_support_in_numeric_strings
|
||||
* https://wiki.php.net/rfc/unicode_escape
|
||||
|
||||
Other language changes
|
||||
----------------------
|
||||
|
||||
. Removed ASP (<%) and script (<script language=php>) tags.
|
||||
(RFC: https://wiki.php.net/rfc/remove_alternative_php_tags)
|
||||
. call_user_method() and call_user_method_array() no longer exists.
|
||||
. PHP 7 doesn't keep original values of arguments passed to user functions,
|
||||
so func_get_arg() and func_get_args() will return current value of argument
|
||||
instead of the actually passed. The following code is going to be affected:
|
||||
function foo($x) { $x = 2; return func_get_arg(0);} var_dump(foo(1));
|
||||
It will now produce 2, not 1.
|
||||
. Function parameters with duplicate name are not allowed anymore. Definitions
|
||||
like “function foo($x,$x) {}” will lead to compile time error.
|
||||
. Indirect variable, property and method references are now interpreted with
|
||||
left-to-right semantics. See details in:
|
||||
https://wiki.php.net/rfc/uniform_variable_syntax#semantic_differences_in_existing_syntax
|
||||
. The global keyword now only accepts simple variables. See details in:
|
||||
https://wiki.php.net/rfc/uniform_variable_syntax#global_keyword_takes_only_simple_variables
|
||||
. The addition of Unicode Codepoint Escape Syntax for double-quoted strings
|
||||
and heredocs means that \u{ followed by an invalid sequence will now error.
|
||||
However, \u without a following { is unaffected, so "\u202e" won't error and
|
||||
will work the same as before.
|
||||
. zend_function.common.num_args don't include the variadic argument anymore.
|
||||
. ob_start() no longer issues an E_ERROR, but instead an E_RECOVERABLE_ERROR in case an
|
||||
output buffer is created in an output buffer handler.
|
||||
. Removed support for assigning the result of new by reference.
|
||||
. Removed support for scoped calls to non-static methods from an incompatible
|
||||
$this context. See details in https://wiki.php.net/rfc/incompat_ctx.
|
||||
. Removed support for #-style comments in ini files. Use ;-style comments
|
||||
instead.
|
||||
. Added zend_memnstr_ex, which is based on string matching sunday algo.
|
||||
. Added zend_memnrstr, zend_memnrstr_ex.
|
||||
. $HTTP_RAW_POST_DATA is no longer available. Use the php://input stream instead.
|
||||
|
||||
Standard library changes
|
||||
========================
|
||||
|
||||
. call_user_method() and call_user_method_array() no longer exists.
|
||||
. ob_start() no longer issues an E_ERROR, but instead an E_RECOVERABLE_ERROR in case an
|
||||
output buffer is created in an output buffer handler.
|
||||
. Added hybrid sorting algo zend_sort for better performance.
|
||||
. Added stable sorting algo zend_insert_sort.
|
||||
. Invalid octal literals in source code now produce compile errors, fixing
|
||||
PHPSadness #31. Previously, the invalid digits (and any following valid
|
||||
digits) were simply ignored, such that 0781 became 7.
|
||||
. Removed dl() function on fpm-fcgi.
|
||||
. Removed support for hexadecimal numeric strings. This means that some
|
||||
operations like == will no longer specially interpret strings containing
|
||||
hexadecimal numbers. Furthermore is_numeric() will not consider hexadecimal
|
||||
strings to be numeric (use FILTER_VALIDATE_INT instead).
|
||||
(RFC: https://wiki.php.net/rfc/remove_hex_support_in_numeric_strings)
|
||||
. $HTTP_RAW_POST_DATA is no longer available. Use the php://input stream instead.
|
||||
|
||||
Other
|
||||
=====
|
||||
|
||||
- Date:
|
||||
. Removed $is_dst parameter from mktime() and gmmktime().
|
||||
@ -170,9 +441,26 @@ PHP X.Y UPGRADE NOTES
|
||||
|
||||
|
||||
========================================
|
||||
8. Removed Extensions
|
||||
8. Removed Extensions and SAPIs
|
||||
========================================
|
||||
|
||||
- sapi/aolserver
|
||||
- sapi/apache
|
||||
- sapi/apache_hooks
|
||||
- sapi/apache2filter
|
||||
- sapi/caudium
|
||||
- sapi/continuity
|
||||
- sapi/isapi
|
||||
- sapi/milter
|
||||
- sapi/phttpd
|
||||
- sapi/pi3web
|
||||
- sapi/roxen
|
||||
- sapi/thttpd
|
||||
- sapi/tux
|
||||
- sapi/webjames
|
||||
- ext/mssql
|
||||
- ext/sybase_ct
|
||||
For more details see https://wiki.php.net/rfc/removal_of_dead_sapis_and_exts
|
||||
|
||||
========================================
|
||||
9. Other Changes to Extensions
|
||||
|
@ -23,4 +23,4 @@ var_dump(key($arr["v"]));
|
||||
int(0)
|
||||
int(0)
|
||||
int(0)
|
||||
NULL
|
||||
int(0)
|
||||
|
@ -23,4 +23,4 @@ int(0)
|
||||
int(0)
|
||||
int(1)
|
||||
int(2)
|
||||
NULL
|
||||
int(0)
|
||||
|
42
Zend/tests/bug69017.phpt
Normal file
42
Zend/tests/bug69017.phpt
Normal file
@ -0,0 +1,42 @@
|
||||
--TEST--
|
||||
#69017 (Fail to push to the empty array with the constant value defined in class scope)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class c1
|
||||
{
|
||||
const ZERO = 0;
|
||||
const ONE = 1;
|
||||
const MAX = PHP_INT_MAX;
|
||||
public static $a1 = array(self::ONE => 'one');
|
||||
public static $a2 = array(self::ZERO => 'zero');
|
||||
public static $a3 = array(self::MAX => 'zero');
|
||||
}
|
||||
|
||||
|
||||
c1::$a1[] = 1;
|
||||
c1::$a2[] = 1;
|
||||
c1::$a3[] = 1;
|
||||
|
||||
var_dump(c1::$a1);
|
||||
var_dump(c1::$a2);
|
||||
var_dump(c1::$a3);
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: Cannot add element to the array as the next element is already occupied in %sbug69017.php on line %d
|
||||
array(2) {
|
||||
[1]=>
|
||||
string(3) "one"
|
||||
[2]=>
|
||||
int(1)
|
||||
}
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(4) "zero"
|
||||
[1]=>
|
||||
int(1)
|
||||
}
|
||||
array(1) {
|
||||
[%d]=>
|
||||
string(4) "zero"
|
||||
}
|
15
Zend/tests/bug69025.phpt
Normal file
15
Zend/tests/bug69025.phpt
Normal file
@ -0,0 +1,15 @@
|
||||
--TEST--
|
||||
Bug #69025 (Invalid read of size 4 when calling __callStatic)
|
||||
--FILE--
|
||||
<?php
|
||||
class A {
|
||||
public static function __callStatic($method, $args)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
A::init();
|
||||
?>
|
||||
OK
|
||||
--EXPECT--
|
||||
OK
|
71
Zend/tests/foreach_003.phpt
Normal file
71
Zend/tests/foreach_003.phpt
Normal file
@ -0,0 +1,71 @@
|
||||
--TEST--
|
||||
Iterator exceptions in foreach by value
|
||||
--FILE--
|
||||
<?php
|
||||
class IT implements Iterator {
|
||||
private $n = 0;
|
||||
private $count = 0;
|
||||
private $trap = null;
|
||||
|
||||
function __construct($count, $trap = null) {
|
||||
$this->count = $count;
|
||||
$this->trap = $trap;
|
||||
}
|
||||
|
||||
function trap($trap) {
|
||||
if ($trap === $this->trap) {
|
||||
throw new Exception($trap);
|
||||
}
|
||||
}
|
||||
|
||||
function rewind() {$this->trap(__FUNCTION__); $this->n = 0;}
|
||||
function valid() {$this->trap(__FUNCTION__); return $this->n < $this->count;}
|
||||
function key() {$this->trap(__FUNCTION__); return $this->n;}
|
||||
function current() {$this->trap(__FUNCTION__); return $this->n;}
|
||||
function next() {$this->trap(__FUNCTION__); $this->n++;}
|
||||
}
|
||||
|
||||
foreach(['rewind', 'valid', 'key', 'current', 'next'] as $trap) {
|
||||
$obj = new IT(3, $trap);
|
||||
try {
|
||||
// IS_CV
|
||||
foreach ($obj as $key => $val) echo "$val\n";
|
||||
} catch (Exception $e) {
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
unset($obj);
|
||||
|
||||
try {
|
||||
// IS_VAR
|
||||
foreach (new IT(3, $trap) as $key => $val) echo "$val\n";
|
||||
} catch (Exception $e) {
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
|
||||
try {
|
||||
// IS_TMP_VAR
|
||||
foreach ((object)new IT(2, $trap) as $key => $val) echo "$val\n";
|
||||
} catch (Exception $e) {
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
rewind
|
||||
rewind
|
||||
rewind
|
||||
valid
|
||||
valid
|
||||
valid
|
||||
key
|
||||
key
|
||||
key
|
||||
current
|
||||
current
|
||||
current
|
||||
0
|
||||
next
|
||||
0
|
||||
next
|
||||
0
|
||||
next
|
65
Zend/tests/foreach_004.phpt
Normal file
65
Zend/tests/foreach_004.phpt
Normal file
@ -0,0 +1,65 @@
|
||||
--TEST--
|
||||
Iterator exceptions in foreach by reference
|
||||
--FILE--
|
||||
<?php
|
||||
class IT extends ArrayIterator {
|
||||
private $n = 0;
|
||||
|
||||
function __construct($trap = null) {
|
||||
parent::__construct([0, 1]);
|
||||
$this->trap = $trap;
|
||||
}
|
||||
|
||||
function trap($trap) {
|
||||
if ($trap === $this->trap) {
|
||||
throw new Exception($trap);
|
||||
}
|
||||
}
|
||||
|
||||
function rewind() {$this->trap(__FUNCTION__); return parent::rewind();}
|
||||
function valid() {$this->trap(__FUNCTION__); return parent::valid();}
|
||||
function key() {$this->trap(__FUNCTION__); return parent::key();}
|
||||
function next() {$this->trap(__FUNCTION__); return parent::next();}
|
||||
}
|
||||
|
||||
foreach(['rewind', 'valid', 'key', 'next'] as $trap) {
|
||||
$obj = new IT($trap);
|
||||
try {
|
||||
// IS_CV
|
||||
foreach ($obj as $key => &$val) echo "$val\n";
|
||||
} catch (Exception $e) {
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
unset($obj);
|
||||
|
||||
try {
|
||||
// IS_VAR
|
||||
foreach (new IT($trap) as $key => &$val) echo "$val\n";
|
||||
} catch (Exception $e) {
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
|
||||
try {
|
||||
// IS_TMP_VAR
|
||||
foreach ((object)new IT($trap) as $key => &$val) echo "$val\n";
|
||||
} catch (Exception $e) {
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
rewind
|
||||
rewind
|
||||
rewind
|
||||
valid
|
||||
valid
|
||||
valid
|
||||
key
|
||||
key
|
||||
key
|
||||
0
|
||||
next
|
||||
0
|
||||
next
|
||||
0
|
||||
next
|
22
Zend/tests/foreach_005.phpt
Normal file
22
Zend/tests/foreach_005.phpt
Normal file
@ -0,0 +1,22 @@
|
||||
--TEST--
|
||||
Nested foreach by reference on the same array
|
||||
--FILE--
|
||||
<?php
|
||||
$a = [1,2,3];
|
||||
foreach($a as &$x) {
|
||||
foreach($a as &$y) {
|
||||
echo "$x-$y\n";
|
||||
$y++;
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
1-1
|
||||
2-2
|
||||
2-3
|
||||
3-2
|
||||
3-3
|
||||
4-4
|
||||
5-3
|
||||
5-4
|
||||
5-5
|
20
Zend/tests/foreach_006.phpt
Normal file
20
Zend/tests/foreach_006.phpt
Normal file
@ -0,0 +1,20 @@
|
||||
--TEST--
|
||||
Foreach by reference on constant
|
||||
--FILE--
|
||||
<?php
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
foreach ([1,2,3] as &$val) {
|
||||
echo "$val\n";
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
1
|
||||
2
|
||||
3
|
||||
1
|
||||
2
|
||||
3
|
||||
1
|
||||
2
|
||||
3
|
13
Zend/tests/foreach_007.phpt
Normal file
13
Zend/tests/foreach_007.phpt
Normal file
@ -0,0 +1,13 @@
|
||||
--TEST--
|
||||
Foreach by reference and inserting new element when we are already at the end
|
||||
--FILE--
|
||||
<?php
|
||||
$a = [1];
|
||||
foreach($a as &$v) {
|
||||
echo "$v\n";
|
||||
$a[1]=2;
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
1
|
||||
2
|
21
Zend/tests/foreach_008.phpt
Normal file
21
Zend/tests/foreach_008.phpt
Normal file
@ -0,0 +1,21 @@
|
||||
--TEST--
|
||||
Nested foreach by reference and array modification
|
||||
--FILE--
|
||||
<?php
|
||||
$a = [0, 1, 2, 3];
|
||||
foreach ($a as &$x) {
|
||||
foreach ($a as &$y) {
|
||||
echo "$x - $y\n";
|
||||
if ($x == 0 && $y == 1) {
|
||||
unset($a[2]);
|
||||
unset($a[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
0 - 0
|
||||
0 - 1
|
||||
0 - 3
|
||||
3 - 0
|
||||
3 - 3
|
40
Zend/tests/foreach_009.phpt
Normal file
40
Zend/tests/foreach_009.phpt
Normal file
@ -0,0 +1,40 @@
|
||||
--TEST--
|
||||
Nested foreach by reference and array modification with resize
|
||||
--FILE--
|
||||
<?php
|
||||
$a = [0, 1, 2, 3, 4, 5, 6, 7];
|
||||
unset($a[0], $a[1], $a[2], $a[3]);
|
||||
foreach ($a as &$ref) {
|
||||
foreach ($a as &$ref2) {
|
||||
echo "$ref-$ref2\n";
|
||||
if ($ref == 5 && $ref2 == 6) {
|
||||
$a[42] = 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
4-4
|
||||
4-5
|
||||
4-6
|
||||
4-7
|
||||
5-4
|
||||
5-5
|
||||
5-6
|
||||
5-7
|
||||
5-8
|
||||
6-4
|
||||
6-5
|
||||
6-6
|
||||
6-7
|
||||
6-8
|
||||
7-4
|
||||
7-5
|
||||
7-6
|
||||
7-7
|
||||
7-8
|
||||
8-4
|
||||
8-5
|
||||
8-6
|
||||
8-7
|
||||
8-8
|
40
Zend/tests/foreach_010.phpt
Normal file
40
Zend/tests/foreach_010.phpt
Normal file
@ -0,0 +1,40 @@
|
||||
--TEST--
|
||||
Nested foreach by value over object and object modification with resize
|
||||
--FILE--
|
||||
<?php
|
||||
$o = (object)['a'=>0, 'b'=>1, 'c'=>2, 'd'=>3, 'e'=>4, 'f'=>5, 'g'=>6, 'h'=>7];
|
||||
unset($o->a, $o->b, $o->c, $o->d);
|
||||
foreach ($o as $v1) {
|
||||
foreach ($o as $v2) {
|
||||
echo "$v1-$v2\n";
|
||||
if ($v1 == 5 && $v2 == 6) {
|
||||
$o->i = 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
4-4
|
||||
4-5
|
||||
4-6
|
||||
4-7
|
||||
5-4
|
||||
5-5
|
||||
5-6
|
||||
5-7
|
||||
5-8
|
||||
6-4
|
||||
6-5
|
||||
6-6
|
||||
6-7
|
||||
6-8
|
||||
7-4
|
||||
7-5
|
||||
7-6
|
||||
7-7
|
||||
7-8
|
||||
8-4
|
||||
8-5
|
||||
8-6
|
||||
8-7
|
||||
8-8
|
19
Zend/tests/foreach_011.phpt
Normal file
19
Zend/tests/foreach_011.phpt
Normal file
@ -0,0 +1,19 @@
|
||||
--TEST--
|
||||
sort() functions precerve foreach by reference iterator pointer
|
||||
--FILE--
|
||||
<?php
|
||||
$a = [1,2,3,4,5,0];
|
||||
foreach($a as &$v) {
|
||||
echo "$v\n";
|
||||
if ($v == 3) {
|
||||
rsort($a);
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
1
|
||||
2
|
||||
3
|
||||
2
|
||||
1
|
||||
0
|
18
Zend/tests/foreach_012.phpt
Normal file
18
Zend/tests/foreach_012.phpt
Normal file
@ -0,0 +1,18 @@
|
||||
--TEST--
|
||||
array_walk() function precerve foreach by reference iterator pointer
|
||||
--FILE--
|
||||
<?php
|
||||
$a = [1,2,3,4,5];
|
||||
foreach($a as &$v) {
|
||||
echo "$v\n";
|
||||
if ($v == 3) {
|
||||
array_walk($a, function (&$x) {$x+=10;});
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
1
|
||||
2
|
||||
3
|
||||
14
|
||||
15
|
17
Zend/tests/foreach_013.phpt
Normal file
17
Zend/tests/foreach_013.phpt
Normal file
@ -0,0 +1,17 @@
|
||||
--TEST--
|
||||
array_push() function precerve foreach by reference iterator pointer
|
||||
--FILE--
|
||||
<?php
|
||||
$a = [1,2,3];
|
||||
foreach($a as &$v) {
|
||||
echo "$v\n";
|
||||
if ($v == 3) {
|
||||
array_push($a, 4);
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
15
Zend/tests/foreach_014.phpt
Normal file
15
Zend/tests/foreach_014.phpt
Normal file
@ -0,0 +1,15 @@
|
||||
--TEST--
|
||||
array_pop() function precerve foreach by reference iterator pointer
|
||||
--FILE--
|
||||
<?php
|
||||
$a = [1,2,3];
|
||||
foreach($a as &$v) {
|
||||
echo "$v\n";
|
||||
if ($v == 2) {
|
||||
array_pop($a);
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
1
|
||||
2
|
18
Zend/tests/foreach_015.phpt
Normal file
18
Zend/tests/foreach_015.phpt
Normal file
@ -0,0 +1,18 @@
|
||||
--TEST--
|
||||
array_shift() function precerve foreach by reference iterator pointer
|
||||
--FILE--
|
||||
<?php
|
||||
$a = [1,2,3,4];
|
||||
foreach($a as &$v) {
|
||||
echo "$v\n";
|
||||
array_shift($a);
|
||||
}
|
||||
var_dump($a);
|
||||
?>
|
||||
--EXPECT--
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
array(0) {
|
||||
}
|
18
Zend/tests/foreach_016.phpt
Normal file
18
Zend/tests/foreach_016.phpt
Normal file
@ -0,0 +1,18 @@
|
||||
--TEST--
|
||||
array_unshift() function precerve foreach by reference iterator pointer
|
||||
--FILE--
|
||||
<?php
|
||||
$a = [1,2,3];
|
||||
foreach($a as &$v) {
|
||||
echo "$v\n";
|
||||
if ($v == 2) {
|
||||
array_unshift($a, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
var_dump(count($a));
|
||||
?>
|
||||
--EXPECT--
|
||||
1
|
||||
2
|
||||
3
|
||||
int(11)
|
111
Zend/tests/foreach_017.phpt
Normal file
111
Zend/tests/foreach_017.phpt
Normal file
@ -0,0 +1,111 @@
|
||||
--TEST--
|
||||
array_splice() function precerve foreach by reference iterator pointer
|
||||
--FILE--
|
||||
<?php
|
||||
/* remove before */
|
||||
$done = 0;
|
||||
$a = [0,1,2,3,4];
|
||||
foreach($a as &$v) {
|
||||
echo "$v\n";
|
||||
if (!$done && $v == 3) {
|
||||
$done = 1;
|
||||
array_splice($a, 1, 2);
|
||||
}
|
||||
}
|
||||
echo "\n";
|
||||
|
||||
/* remove after */
|
||||
$done = 0;
|
||||
$a = [0,1,2,3,4];
|
||||
foreach($a as &$v) {
|
||||
echo "$v\n";
|
||||
if (!$done && $v == 0) {
|
||||
$done = 1;
|
||||
array_splice($a, 2, 2);
|
||||
}
|
||||
}
|
||||
echo "\n";
|
||||
|
||||
/* remove current */
|
||||
$done = 0;
|
||||
$a = [0,1,2,3,4];
|
||||
foreach($a as &$v) {
|
||||
echo "$v\n";
|
||||
if (!$done && $v == 2) {
|
||||
$done = 1;
|
||||
array_splice($a, 1, 3);
|
||||
}
|
||||
}
|
||||
echo "\n";
|
||||
|
||||
$replacement = ['x', 'y', 'z'];
|
||||
|
||||
/* replace before */
|
||||
$done = 0;
|
||||
$a = [0,1,2,3,4];
|
||||
foreach($a as &$v) {
|
||||
echo "$v\n";
|
||||
if ($done && $v == 3) {
|
||||
$done = 1;
|
||||
array_splice($a, 1, 2, $replacement);
|
||||
}
|
||||
}
|
||||
echo "\n";
|
||||
|
||||
/* replace after */
|
||||
$done = 0;
|
||||
$a = [0,1,2,3,4];
|
||||
foreach($a as &$v) {
|
||||
echo "$v\n";
|
||||
if (!$done && $v == 0) {
|
||||
$done = 1;
|
||||
array_splice($a, 2, 2, $replacement);
|
||||
}
|
||||
}
|
||||
echo "\n";
|
||||
|
||||
/* replace current */
|
||||
$done = 0;
|
||||
$a = [0,1,2,3,4];
|
||||
foreach($a as &$v) {
|
||||
echo "$v\n";
|
||||
if (!$done && $v == 2) {
|
||||
$done = 1;
|
||||
array_splice($a, 1, 3, $replacement);
|
||||
}
|
||||
}
|
||||
echo "\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
0
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
|
||||
0
|
||||
1
|
||||
4
|
||||
|
||||
0
|
||||
1
|
||||
2
|
||||
4
|
||||
|
||||
0
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
|
||||
0
|
||||
1
|
||||
x
|
||||
y
|
||||
z
|
||||
4
|
||||
|
||||
0
|
||||
1
|
||||
2
|
||||
4
|
27
Zend/tests/varSyntax/constClassMemberAccess.phpt
Normal file
27
Zend/tests/varSyntax/constClassMemberAccess.phpt
Normal file
@ -0,0 +1,27 @@
|
||||
--TEST--
|
||||
Const class member access with deference
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class A {
|
||||
const A = ['a' => ['b' => 'c']];
|
||||
}
|
||||
|
||||
var_dump(A::A);
|
||||
var_dump(A::A['a']);
|
||||
var_dump(A::A['a']['b']);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
array(1) {
|
||||
["a"]=>
|
||||
array(1) {
|
||||
["b"]=>
|
||||
string(1) "c"
|
||||
}
|
||||
}
|
||||
array(1) {
|
||||
["b"]=>
|
||||
string(1) "c"
|
||||
}
|
||||
string(1) "c"
|
12
Zend/zend.c
12
Zend/zend.c
@ -120,7 +120,7 @@ static HashTable *global_class_table = NULL;
|
||||
static HashTable *global_constants_table = NULL;
|
||||
static HashTable *global_auto_globals_table = NULL;
|
||||
static HashTable *global_persistent_list = NULL;
|
||||
ZEND_TSRMLS_CACHE_DEFINE;
|
||||
ZEND_TSRMLS_CACHE_DEFINE();
|
||||
#endif
|
||||
|
||||
ZEND_API zend_utility_values zend_uv;
|
||||
@ -465,7 +465,7 @@ static void compiler_globals_dtor(zend_compiler_globals *compiler_globals) /* {{
|
||||
|
||||
static void executor_globals_ctor(zend_executor_globals *executor_globals) /* {{{ */
|
||||
{
|
||||
ZEND_TSRMLS_CACHE_UPDATE;
|
||||
ZEND_TSRMLS_CACHE_UPDATE();
|
||||
zend_startup_constants();
|
||||
zend_copy_constants(EG(zend_constants), GLOBAL_CONSTANTS_TABLE);
|
||||
zend_init_rsrc_plist();
|
||||
@ -550,8 +550,9 @@ static zend_bool php_auto_globals_create_globals(zend_string *name) /* {{{ */
|
||||
zval globals;
|
||||
|
||||
ZVAL_ARR(&globals, &EG(symbol_table));
|
||||
Z_TYPE_INFO_P(&globals) = IS_ARRAY | (IS_TYPE_SYMBOLTABLE << Z_TYPE_FLAGS_SHIFT);
|
||||
ZVAL_NEW_REF(&globals, &globals);
|
||||
zend_hash_update(&EG(symbol_table).ht, name, &globals);
|
||||
zend_hash_update(&EG(symbol_table), name, &globals);
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
@ -563,7 +564,7 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions) /
|
||||
zend_executor_globals *executor_globals;
|
||||
extern ZEND_API ts_rsrc_id ini_scanner_globals_id;
|
||||
extern ZEND_API ts_rsrc_id language_scanner_globals_id;
|
||||
ZEND_TSRMLS_CACHE_UPDATE;
|
||||
ZEND_TSRMLS_CACHE_UPDATE();
|
||||
#else
|
||||
extern zend_ini_scanner_globals ini_scanner_globals;
|
||||
extern zend_php_scanner_globals language_scanner_globals;
|
||||
@ -1129,8 +1130,7 @@ static void zend_error_va_list(int type, const char *format, va_list args)
|
||||
if (!symbol_table) {
|
||||
ZVAL_NULL(¶ms[4]);
|
||||
} else {
|
||||
ZVAL_NEW_ARR(¶ms[4]);
|
||||
zend_array_dup(Z_ARRVAL(params[4]), &symbol_table->ht);
|
||||
ZVAL_ARR(¶ms[4], zend_array_dup(symbol_table));
|
||||
}
|
||||
|
||||
ZVAL_COPY_VALUE(&orig_user_error_handler, &EG(user_error_handler));
|
||||
|
14
Zend/zend.h
14
Zend/zend.h
@ -62,19 +62,19 @@
|
||||
|
||||
#ifdef ZEND_ENABLE_STATIC_TSRMLS_CACHE
|
||||
#define ZEND_TSRMG TSRMG_STATIC
|
||||
#define ZEND_TSRMLS_CACHE_EXTERN TSRMLS_CACHE_EXTERN
|
||||
#define ZEND_TSRMLS_CACHE_DEFINE TSRMLS_CACHE_DEFINE
|
||||
#define ZEND_TSRMLS_CACHE_UPDATE TSRMLS_CACHE_UPDATE
|
||||
#define ZEND_TSRMLS_CACHE_EXTERN() TSRMLS_CACHE_EXTERN()
|
||||
#define ZEND_TSRMLS_CACHE_DEFINE() TSRMLS_CACHE_DEFINE()
|
||||
#define ZEND_TSRMLS_CACHE_UPDATE() TSRMLS_CACHE_UPDATE()
|
||||
#define ZEND_TSRMLS_CACHE TSRMLS_CACHE
|
||||
#else
|
||||
#define ZEND_TSRMG TSRMG
|
||||
#define ZEND_TSRMLS_CACHE_EXTERN
|
||||
#define ZEND_TSRMLS_CACHE_DEFINE
|
||||
#define ZEND_TSRMLS_CACHE_UPDATE
|
||||
#define ZEND_TSRMLS_CACHE_EXTERN()
|
||||
#define ZEND_TSRMLS_CACHE_DEFINE()
|
||||
#define ZEND_TSRMLS_CACHE_UPDATE()
|
||||
#define ZEND_TSRMLS_CACHE
|
||||
#endif
|
||||
|
||||
ZEND_TSRMLS_CACHE_EXTERN;
|
||||
ZEND_TSRMLS_CACHE_EXTERN();
|
||||
|
||||
#ifdef HAVE_NORETURN
|
||||
# ifdef ZEND_NORETRUN_ALIAS
|
||||
|
@ -911,7 +911,7 @@ ZEND_API int zend_parse_method_parameters_ex(int flags, int num_args, zval *this
|
||||
/* }}} */
|
||||
|
||||
/* Argument parsing API -- andrei */
|
||||
ZEND_API int _array_init(zval *arg, uint size ZEND_FILE_LINE_DC) /* {{{ */
|
||||
ZEND_API int _array_init(zval *arg, uint32_t size ZEND_FILE_LINE_DC) /* {{{ */
|
||||
{
|
||||
ZVAL_NEW_ARR(arg);
|
||||
_zend_hash_init(Z_ARRVAL_P(arg), size, ZVAL_PTR_DTOR, 0 ZEND_FILE_LINE_RELAY_CC);
|
||||
@ -1110,11 +1110,14 @@ ZEND_API void object_properties_load(zend_object *object, HashTable *properties)
|
||||
* calling zend_merge_properties(). */
|
||||
ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *class_type, HashTable *properties ZEND_FILE_LINE_DC) /* {{{ */
|
||||
{
|
||||
if (class_type->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
|
||||
char *what = (class_type->ce_flags & ZEND_ACC_INTERFACE) ? "interface"
|
||||
:((class_type->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) ? "trait"
|
||||
: "abstract class";
|
||||
zend_error(E_ERROR, "Cannot instantiate %s %s", what, class_type->name->val);
|
||||
if (class_type->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
|
||||
if (class_type->ce_flags & ZEND_ACC_INTERFACE) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot instantiate interface %s", class_type->name->val);
|
||||
} else if (class_type->ce_flags & ZEND_ACC_TRAIT) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot instantiate trait %s", class_type->name->val);
|
||||
} else {
|
||||
zend_error_noreturn(E_ERROR, "Cannot instantiate abstract class %s", class_type->name->val);
|
||||
}
|
||||
}
|
||||
|
||||
zend_update_class_constants(class_type);
|
||||
|
@ -372,7 +372,7 @@ ZEND_API char *zend_get_type_by_const(int type);
|
||||
#define object_init(arg) _object_init((arg) ZEND_FILE_LINE_CC)
|
||||
#define object_init_ex(arg, ce) _object_init_ex((arg), (ce) ZEND_FILE_LINE_CC)
|
||||
#define object_and_properties_init(arg, ce, properties) _object_and_properties_init((arg), (ce), (properties) ZEND_FILE_LINE_CC)
|
||||
ZEND_API int _array_init(zval *arg, uint size ZEND_FILE_LINE_DC);
|
||||
ZEND_API int _array_init(zval *arg, uint32_t size ZEND_FILE_LINE_DC);
|
||||
ZEND_API int _object_init(zval *arg ZEND_FILE_LINE_DC);
|
||||
ZEND_API int _object_init_ex(zval *arg, zend_class_entry *ce ZEND_FILE_LINE_DC);
|
||||
ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *ce, HashTable *properties ZEND_FILE_LINE_DC);
|
||||
|
@ -2388,7 +2388,7 @@ static void alloc_globals_ctor(zend_alloc_globals *alloc_globals)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
ZEND_TSRMLS_CACHE_UPDATE;
|
||||
ZEND_TSRMLS_CACHE_UPDATE();
|
||||
alloc_globals->mm_heap = zend_mm_init();
|
||||
}
|
||||
|
||||
|
@ -1140,8 +1140,7 @@ ZEND_FUNCTION(get_object_vars)
|
||||
|
||||
if (!zobj->ce->default_properties_count && properties == zobj->properties) {
|
||||
/* fast copy */
|
||||
ZVAL_NEW_ARR(return_value);
|
||||
zend_array_dup(Z_ARRVAL_P(return_value), properties);
|
||||
ZVAL_ARR(return_value, zend_array_dup(properties));
|
||||
} else {
|
||||
array_init_size(return_value, zend_hash_num_elements(properties));
|
||||
|
||||
@ -1378,14 +1377,15 @@ ZEND_FUNCTION(class_exists)
|
||||
} else {
|
||||
lc_name = zend_string_tolower(class_name);
|
||||
}
|
||||
|
||||
ce = zend_hash_find_ptr(EG(class_table), lc_name);
|
||||
zend_string_release(lc_name);
|
||||
RETURN_BOOL(ce && !((ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT)) > ZEND_ACC_EXPLICIT_ABSTRACT_CLASS));
|
||||
} else {
|
||||
ce = zend_lookup_class(class_name);
|
||||
}
|
||||
|
||||
ce = zend_lookup_class(class_name);
|
||||
if (ce) {
|
||||
RETURN_BOOL((ce->ce_flags & (ZEND_ACC_INTERFACE | (ZEND_ACC_TRAIT - ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))) == 0);
|
||||
RETURN_BOOL((ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT)) == 0);
|
||||
} else {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
@ -1462,14 +1462,15 @@ ZEND_FUNCTION(trait_exists)
|
||||
} else {
|
||||
lc_name = zend_string_tolower(trait_name);
|
||||
}
|
||||
|
||||
ce = zend_hash_find_ptr(EG(class_table), lc_name);
|
||||
zend_string_release(lc_name);
|
||||
RETURN_BOOL(ce && ((ce->ce_flags & ZEND_ACC_TRAIT) > ZEND_ACC_EXPLICIT_ABSTRACT_CLASS));
|
||||
} else {
|
||||
ce = zend_lookup_class(trait_name);
|
||||
}
|
||||
|
||||
ce = zend_lookup_class(trait_name);
|
||||
if (ce) {
|
||||
RETURN_BOOL((ce->ce_flags & ZEND_ACC_TRAIT) > ZEND_ACC_EXPLICIT_ABSTRACT_CLASS);
|
||||
RETURN_BOOL((ce->ce_flags & ZEND_ACC_TRAIT) != 0);
|
||||
} else {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
@ -1806,7 +1807,7 @@ ZEND_FUNCTION(get_declared_traits)
|
||||
Returns an array of all declared classes. */
|
||||
ZEND_FUNCTION(get_declared_classes)
|
||||
{
|
||||
uint32_t mask = ZEND_ACC_INTERFACE | (ZEND_ACC_TRAIT & ~ZEND_ACC_EXPLICIT_ABSTRACT_CLASS);
|
||||
uint32_t mask = ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT;
|
||||
uint32_t comply = 0;
|
||||
|
||||
if (zend_parse_parameters_none() == FAILURE) {
|
||||
@ -1881,8 +1882,7 @@ ZEND_FUNCTION(get_defined_vars)
|
||||
{
|
||||
zend_array *symbol_table = zend_rebuild_symbol_table();
|
||||
|
||||
ZVAL_NEW_ARR(return_value);
|
||||
zend_array_dup(Z_ARRVAL_P(return_value), &symbol_table->ht);
|
||||
ZVAL_ARR(return_value, zend_array_dup(symbol_table));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -349,8 +349,7 @@ static HashTable *zend_closure_get_debug_info(zval *object, int *is_temp) /* {{{
|
||||
if (closure->debug_info->u.v.nApplyCount == 0) {
|
||||
if (closure->func.type == ZEND_USER_FUNCTION && closure->func.op_array.static_variables) {
|
||||
HashTable *static_variables = closure->func.op_array.static_variables;
|
||||
ZVAL_NEW_ARR(&val);
|
||||
zend_array_dup(Z_ARRVAL(val), static_variables);
|
||||
ZVAL_ARR(&val, zend_array_dup(static_variables));
|
||||
zend_hash_str_update(closure->debug_info, "static", sizeof("static")-1, &val);
|
||||
}
|
||||
|
||||
|
@ -895,7 +895,7 @@ static int generate_free_loop_var(znode *var) /* {{{ */
|
||||
{
|
||||
zend_op *opline = get_next_op(CG(active_op_array));
|
||||
|
||||
opline->opcode = ZEND_FREE;
|
||||
opline->opcode = var->flag ? ZEND_FE_FREE : ZEND_FREE;
|
||||
SET_NODE(opline->op1, var);
|
||||
SET_UNUSED(opline->op2);
|
||||
}
|
||||
@ -931,10 +931,7 @@ ZEND_API void function_add_ref(zend_function *function) /* {{{ */
|
||||
|
||||
(*op_array->refcount)++;
|
||||
if (op_array->static_variables) {
|
||||
HashTable *static_variables = op_array->static_variables;
|
||||
|
||||
ALLOC_HASHTABLE(op_array->static_variables);
|
||||
zend_array_dup(op_array->static_variables, static_variables);
|
||||
op_array->static_variables = zend_array_dup(op_array->static_variables);
|
||||
}
|
||||
op_array->run_time_cache = NULL;
|
||||
} else if (function->type == ZEND_INTERNAL_FUNCTION) {
|
||||
@ -1048,12 +1045,6 @@ ZEND_API zend_class_entry *do_bind_inherited_class(const zend_op_array *op_array
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (parent_ce->ce_flags & ZEND_ACC_INTERFACE) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot extend from interface %s", ce->name->val, parent_ce->name->val);
|
||||
} else if ((parent_ce->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot extend from trait %s", ce->name->val, parent_ce->name->val);
|
||||
}
|
||||
|
||||
zend_do_inheritance(ce, parent_ce);
|
||||
|
||||
ce->refcount++;
|
||||
@ -1235,13 +1226,14 @@ static zend_bool zend_try_ct_eval_const(zval *zv, zend_string *name, zend_bool i
|
||||
{
|
||||
zend_constant *c;
|
||||
|
||||
if (!(CG(compiler_options) & ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION)) {
|
||||
/* Substitute case-sensitive (or lowercase) persistent constants */
|
||||
c = zend_hash_find_ptr(EG(zend_constants), name);
|
||||
if (c && (c->flags & CONST_PERSISTENT)) {
|
||||
ZVAL_DUP(zv, &c->value);
|
||||
return 1;
|
||||
}
|
||||
/* Substitute case-sensitive (or lowercase) constants */
|
||||
c = zend_hash_find_ptr(EG(zend_constants), name);
|
||||
if (c && (
|
||||
((c->flags & CONST_PERSISTENT) && !(CG(compiler_options) & ZEND_COMPILE_NO_PERSISTENT_CONSTANT_SUBSTITUTION))
|
||||
|| (Z_TYPE(c->value) < IS_OBJECT && !(CG(compiler_options) & ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION))
|
||||
)) {
|
||||
ZVAL_DUP(zv, &c->value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
{
|
||||
@ -1264,6 +1256,38 @@ static zend_bool zend_try_ct_eval_const(zval *zv, zend_string *name, zend_bool i
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_bool zend_try_ct_eval_class_const(zval *zv, zend_string *class_name, zend_string *name) /* {{{ */
|
||||
{
|
||||
uint32_t fetch_type = zend_get_class_fetch_type(class_name);
|
||||
zval *c;
|
||||
|
||||
if (CG(active_class_entry) && (fetch_type == ZEND_FETCH_CLASS_SELF || (fetch_type == ZEND_FETCH_CLASS_DEFAULT && zend_string_equals_ci(class_name, CG(active_class_entry)->name)))) {
|
||||
c = zend_hash_find(&CG(active_class_entry)->constants_table, name);
|
||||
} else if (fetch_type == ZEND_FETCH_CLASS_DEFAULT && !(CG(compiler_options) & ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION)) {
|
||||
zend_class_entry *ce = zend_hash_find_ptr_lc(CG(class_table), class_name->val, class_name->len);
|
||||
if (ce) {
|
||||
c = zend_hash_find(&ce->constants_table, name);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (CG(compiler_options) & ZEND_COMPILE_NO_PERSISTENT_CONSTANT_SUBSTITUTION) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Substitute case-sensitive (or lowercase) persistent class constants */
|
||||
if (c && Z_TYPE_P(c) < IS_OBJECT) {
|
||||
ZVAL_DUP(zv, c);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void zend_init_list(void *result, void *item) /* {{{ */
|
||||
{
|
||||
void** list = emalloc(sizeof(void*) * 2);
|
||||
@ -1343,6 +1367,19 @@ void zend_do_extended_fcall_end(void) /* {{{ */
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
zend_bool zend_is_auto_global_str(char *name, size_t len) /* {{{ */ {
|
||||
zend_auto_global *auto_global;
|
||||
|
||||
if ((auto_global = zend_hash_str_find_ptr(CG(auto_globals), name, len)) != NULL) {
|
||||
if (auto_global->armed) {
|
||||
auto_global->armed = auto_global->auto_global_callback(auto_global->name);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
zend_bool zend_is_auto_global(zend_string *name) /* {{{ */
|
||||
{
|
||||
zend_auto_global *auto_global;
|
||||
@ -1695,13 +1732,6 @@ ZEND_API size_t zend_dirname(char *path, size_t len)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static inline zend_bool zend_string_equals_str_ci(zend_string *str1, zend_string *str2) /* {{{ */
|
||||
{
|
||||
return str1->len == str2->len
|
||||
&& !zend_binary_strcasecmp(str1->val, str1->len, str2->val, str2->len);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void zend_adjust_for_fetch_type(zend_op *opline, uint32_t type) /* {{{ */
|
||||
{
|
||||
switch (type & BP_VAR_MASK) {
|
||||
@ -3494,32 +3524,19 @@ void zend_compile_foreach(zend_ast *ast) /* {{{ */
|
||||
}
|
||||
|
||||
opnum_reset = get_next_op_number(CG(active_op_array));
|
||||
opline = zend_emit_op(&reset_node, ZEND_FE_RESET, &expr_node, NULL);
|
||||
if (by_ref && is_variable) {
|
||||
opline->extended_value = ZEND_FE_FETCH_BYREF;
|
||||
}
|
||||
opline = zend_emit_op(&reset_node, by_ref ? ZEND_FE_RESET_RW : ZEND_FE_RESET_R, &expr_node, NULL);
|
||||
|
||||
reset_node.flag = 1; /* generate FE_FREE */
|
||||
zend_stack_push(&CG(loop_var_stack), &reset_node);
|
||||
|
||||
opnum_fetch = get_next_op_number(CG(active_op_array));
|
||||
opline = zend_emit_op(&value_node, ZEND_FE_FETCH, &reset_node, NULL);
|
||||
if (by_ref) {
|
||||
opline->extended_value |= ZEND_FE_FETCH_BYREF;
|
||||
}
|
||||
opline = zend_emit_op(&value_node, by_ref ? ZEND_FE_FETCH_RW : ZEND_FE_FETCH_R, &reset_node, NULL);
|
||||
if (key_ast) {
|
||||
opline->extended_value |= ZEND_FE_FETCH_WITH_KEY;
|
||||
opline->extended_value = 1;
|
||||
}
|
||||
|
||||
opline = zend_emit_op(NULL, ZEND_OP_DATA, NULL, NULL);
|
||||
|
||||
/* Allocate enough space to keep HashPointer on VM stack */
|
||||
opline->op1_type = IS_TMP_VAR;
|
||||
opline->op1.var = get_temporary_variable(CG(active_op_array));
|
||||
if (sizeof(HashPointer) > sizeof(zval)) {
|
||||
/* Make sure 1 zval is enough for HashPointer (2 must be enough) */
|
||||
get_temporary_variable(CG(active_op_array));
|
||||
}
|
||||
|
||||
if (key_ast) {
|
||||
zend_make_tmp_result(&key_node, opline);
|
||||
}
|
||||
@ -3610,6 +3627,7 @@ void zend_compile_switch(zend_ast *ast) /* {{{ */
|
||||
|
||||
zend_compile_expr(&expr_node, expr_ast);
|
||||
|
||||
expr_node.flag = 0;
|
||||
zend_stack_push(&CG(loop_var_stack), &expr_node);
|
||||
|
||||
zend_begin_loop();
|
||||
@ -4011,9 +4029,13 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, zend_bool is_
|
||||
"Variadic parameter cannot have a default value");
|
||||
}
|
||||
} else if (default_ast) {
|
||||
/* we cannot substitute constants here or it will break ReflectionParameter::getDefaultValueConstantName() and ReflectionParameter::isDefaultValueConstant() */
|
||||
uint32_t cops = CG(compiler_options);
|
||||
CG(compiler_options) |= ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION | ZEND_COMPILE_NO_PERSISTENT_CONSTANT_SUBSTITUTION;
|
||||
opcode = ZEND_RECV_INIT;
|
||||
default_node.op_type = IS_CONST;
|
||||
zend_const_expr_to_zval(&default_node.u.constant, default_ast);
|
||||
CG(compiler_options) = cops;
|
||||
} else {
|
||||
opcode = ZEND_RECV;
|
||||
default_node.op_type = IS_UNUSED;
|
||||
@ -4128,7 +4150,7 @@ void zend_begin_method_decl(zend_op_array *op_array, zend_string *name, zend_boo
|
||||
{
|
||||
zend_class_entry *ce = CG(active_class_entry);
|
||||
zend_bool in_interface = (ce->ce_flags & ZEND_ACC_INTERFACE) != 0;
|
||||
zend_bool in_trait = ZEND_CE_IS_TRAIT(ce);
|
||||
zend_bool in_trait = (ce->ce_flags & ZEND_ACC_TRAIT) != 0;
|
||||
zend_bool is_public = (op_array->fn_flags & ZEND_ACC_PUBLIC) != 0;
|
||||
zend_bool is_static = (op_array->fn_flags & ZEND_ACC_STATIC) != 0;
|
||||
|
||||
@ -4221,7 +4243,7 @@ void zend_begin_method_decl(zend_op_array *op_array, zend_string *name, zend_boo
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!in_trait && zend_string_equals_str_ci(lcname, ce->name)) {
|
||||
if (!in_trait && zend_string_equals_ci(lcname, ce->name)) {
|
||||
if (!ce->constructor) {
|
||||
ce->constructor = (zend_function *) op_array;
|
||||
}
|
||||
@ -4313,7 +4335,7 @@ static void zend_begin_func_decl(znode *result, zend_op_array *op_array, zend_as
|
||||
|
||||
if (CG(current_import_function)) {
|
||||
zend_string *import_name = zend_hash_find_ptr(CG(current_import_function), lcname);
|
||||
if (import_name && !zend_string_equals_str_ci(lcname, import_name)) {
|
||||
if (import_name && !zend_string_equals_ci(lcname, import_name)) {
|
||||
zend_error(E_COMPILE_ERROR, "Cannot declare function %s "
|
||||
"because the name is already in use", name->val);
|
||||
}
|
||||
@ -4490,7 +4512,7 @@ void zend_compile_class_const_decl(zend_ast *ast) /* {{{ */
|
||||
zend_string *name = zend_ast_get_str(name_ast);
|
||||
zval value_zv;
|
||||
|
||||
if (ZEND_CE_IS_TRAIT(ce)) {
|
||||
if ((ce->ce_flags & ZEND_ACC_TRAIT) != 0) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Traits cannot have constants");
|
||||
return;
|
||||
}
|
||||
@ -4709,7 +4731,7 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */
|
||||
zend_string_addref(name);
|
||||
}
|
||||
|
||||
if (import_name && !zend_string_equals_str_ci(lcname, import_name)) {
|
||||
if (import_name && !zend_string_equals_ci(lcname, import_name)) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare class %s "
|
||||
"because the name is already in use", name->val);
|
||||
}
|
||||
@ -4887,7 +4909,7 @@ static char *zend_get_use_type_str(uint32_t type) /* {{{ */
|
||||
|
||||
static void zend_check_already_in_use(uint32_t type, zend_string *old_name, zend_string *new_name, zend_string *check_name) /* {{{ */
|
||||
{
|
||||
if (zend_string_equals_str_ci(old_name, check_name)) {
|
||||
if (zend_string_equals_ci(old_name, check_name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -5200,7 +5222,7 @@ static zend_bool zend_try_ct_eval_magic_const(zval *zv, zend_ast *ast) /* {{{ */
|
||||
break;
|
||||
case T_CLASS_C:
|
||||
if (ce) {
|
||||
if (ZEND_CE_IS_TRAIT(ce)) {
|
||||
if ((ce->ce_flags & ZEND_ACC_TRAIT) != 0) {
|
||||
return 0;
|
||||
} else {
|
||||
ZVAL_STR_COPY(zv, ce->name);
|
||||
@ -5210,7 +5232,7 @@ static zend_bool zend_try_ct_eval_magic_const(zval *zv, zend_ast *ast) /* {{{ */
|
||||
}
|
||||
break;
|
||||
case T_TRAIT_C:
|
||||
if (ce && ZEND_CE_IS_TRAIT(ce)) {
|
||||
if (ce && (ce->ce_flags & ZEND_ACC_TRAIT) != 0) {
|
||||
ZVAL_STR_COPY(zv, ce->name);
|
||||
} else {
|
||||
ZVAL_EMPTY_STRING(zv);
|
||||
@ -5942,31 +5964,33 @@ void zend_compile_class_const(znode *result, zend_ast *ast) /* {{{ */
|
||||
zend_ast *const_ast = ast->child[1];
|
||||
|
||||
znode class_node, const_node;
|
||||
zend_op *opline, *class_op = NULL;
|
||||
zend_op *opline;
|
||||
zend_string *resolved_name;
|
||||
|
||||
if (zend_is_const_default_class_ref(class_ast)) {
|
||||
class_node.op_type = IS_CONST;
|
||||
ZVAL_STR(&class_node.u.constant, zend_resolve_class_name_ast(class_ast));
|
||||
} else {
|
||||
class_op = zend_compile_class_ref(&class_node, class_ast);
|
||||
}
|
||||
|
||||
zend_compile_expr(&const_node, const_ast);
|
||||
|
||||
if (class_op && const_node.op_type == IS_CONST && class_op->extended_value == ZEND_FETCH_CLASS_SELF && Z_TYPE(const_node.u.constant) == IS_STRING && CG(active_class_entry)) {
|
||||
zval *const_zv = zend_hash_find(&CG(active_class_entry)->constants_table, Z_STR(const_node.u.constant));
|
||||
if (const_zv && Z_TYPE_P(const_zv) < IS_CONSTANT) {
|
||||
CG(active_op_array)->last--;
|
||||
CG(active_op_array)->T--;
|
||||
zend_eval_const_expr(&class_ast);
|
||||
zend_eval_const_expr(&const_ast);
|
||||
|
||||
if (class_ast->kind == ZEND_AST_ZVAL) {
|
||||
resolved_name = zend_resolve_class_name_ast(class_ast);
|
||||
if (const_ast->kind == ZEND_AST_ZVAL && zend_try_ct_eval_class_const(&result->u.constant, resolved_name, zend_ast_get_str(const_ast))) {
|
||||
result->op_type = IS_CONST;
|
||||
ZVAL_COPY(&result->u.constant, const_zv);
|
||||
|
||||
zend_string_release(Z_STR(const_node.u.constant));
|
||||
zend_string_release(resolved_name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (zend_is_const_default_class_ref(class_ast)) {
|
||||
class_node.op_type = IS_CONST;
|
||||
ZVAL_STR(&class_node.u.constant, resolved_name);
|
||||
} else {
|
||||
if (class_ast->kind == ZEND_AST_ZVAL) {
|
||||
zend_string_release(resolved_name);
|
||||
}
|
||||
zend_compile_class_ref(&class_node, class_ast);
|
||||
}
|
||||
|
||||
zend_compile_expr(&const_node, const_ast);
|
||||
|
||||
opline = zend_emit_op_tmp(result, ZEND_FETCH_CONSTANT, NULL, &const_node);
|
||||
|
||||
zend_set_class_name_op1(opline, &class_node);
|
||||
@ -6006,8 +6030,8 @@ void zend_compile_resolve_class_name(znode *result, zend_ast *ast) /* {{{ */
|
||||
ZVAL_STR_COPY(&result->u.constant, CG(active_class_entry)->name);
|
||||
}
|
||||
break;
|
||||
case ZEND_FETCH_CLASS_STATIC:
|
||||
case ZEND_FETCH_CLASS_PARENT:
|
||||
case ZEND_FETCH_CLASS_STATIC:
|
||||
case ZEND_FETCH_CLASS_PARENT:
|
||||
if (!CG(active_class_entry)) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR,
|
||||
"Cannot access %s::class when no class scope is active",
|
||||
@ -6097,7 +6121,7 @@ void zend_compile_magic_const(znode *result, zend_ast *ast) /* {{{ */
|
||||
|
||||
ZEND_ASSERT(ast->attr == T_CLASS_C &&
|
||||
CG(active_class_entry) &&
|
||||
ZEND_CE_IS_TRAIT(CG(active_class_entry)));
|
||||
(CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) != 0);
|
||||
|
||||
{
|
||||
zend_ast *const_ast = zend_ast_create(ZEND_AST_CONST,
|
||||
@ -6232,7 +6256,7 @@ void zend_compile_const_expr_magic_const(zend_ast **ast_ptr) /* {{{ */
|
||||
/* Other cases already resolved by constant folding */
|
||||
ZEND_ASSERT(ast->attr == T_CLASS_C &&
|
||||
CG(active_class_entry) &&
|
||||
ZEND_CE_IS_TRAIT(CG(active_class_entry)));
|
||||
(CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) != 0);
|
||||
|
||||
{
|
||||
zval const_zv;
|
||||
@ -6684,6 +6708,30 @@ void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
|
||||
zend_string_release(resolved_name);
|
||||
break;
|
||||
}
|
||||
case ZEND_AST_CLASS_CONST:
|
||||
{
|
||||
zend_ast *class_ast = ast->child[0];
|
||||
zend_ast *name_ast = ast->child[1];
|
||||
zend_string *resolved_name;
|
||||
|
||||
zend_eval_const_expr(&class_ast);
|
||||
zend_eval_const_expr(&name_ast);
|
||||
|
||||
if (class_ast->kind != ZEND_AST_ZVAL || name_ast->kind != ZEND_AST_ZVAL) {
|
||||
return;
|
||||
}
|
||||
|
||||
resolved_name = zend_resolve_class_name_ast(class_ast);
|
||||
|
||||
if (!zend_try_ct_eval_class_const(&result, resolved_name, zend_ast_get_str(name_ast))) {
|
||||
zend_string_release(resolved_name);
|
||||
return;
|
||||
}
|
||||
|
||||
zend_string_release(resolved_name);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
@ -95,7 +95,8 @@ typedef union _znode_op {
|
||||
} znode_op;
|
||||
|
||||
typedef struct _znode { /* used only during compilation */
|
||||
int op_type;
|
||||
zend_uchar op_type;
|
||||
zend_uchar flag;
|
||||
union {
|
||||
znode_op op;
|
||||
zval constant; /* replaced by literal/zv */
|
||||
@ -190,8 +191,8 @@ typedef struct _zend_try_catch_element {
|
||||
/* ZEND_ACC_EXPLICIT_ABSTRACT_CLASS denotes that a class was explicitly defined as abstract by using the keyword. */
|
||||
#define ZEND_ACC_IMPLICIT_ABSTRACT_CLASS 0x10
|
||||
#define ZEND_ACC_EXPLICIT_ABSTRACT_CLASS 0x20
|
||||
#define ZEND_ACC_INTERFACE 0x80
|
||||
#define ZEND_ACC_TRAIT 0x120
|
||||
#define ZEND_ACC_INTERFACE 0x40
|
||||
#define ZEND_ACC_TRAIT 0x80
|
||||
|
||||
/* method flags (visibility) */
|
||||
/* The order of those must be kept - public < protected < private */
|
||||
@ -257,8 +258,6 @@ typedef struct _zend_try_catch_element {
|
||||
/* Function has a return type hint (or class has such non-private function) */
|
||||
#define ZEND_ACC_HAS_RETURN_TYPE 0x40000000
|
||||
|
||||
#define ZEND_CE_IS_TRAIT(ce) (((ce)->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT)
|
||||
|
||||
char *zend_visibility_string(uint32_t fn_flags);
|
||||
|
||||
typedef struct _zend_property_info {
|
||||
@ -732,6 +731,7 @@ typedef struct _zend_auto_global {
|
||||
ZEND_API int zend_register_auto_global(zend_string *name, zend_bool jit, zend_auto_global_callback auto_global_callback);
|
||||
ZEND_API void zend_activate_auto_globals(void);
|
||||
ZEND_API zend_bool zend_is_auto_global(zend_string *name);
|
||||
ZEND_API zend_bool zend_is_auto_global_str(char *name, size_t len);
|
||||
ZEND_API size_t zend_dirname(char *path, size_t len);
|
||||
|
||||
int zendlex(zend_parser_stack_elem *elem);
|
||||
@ -834,9 +834,6 @@ ZEND_API void zend_assert_valid_class_name(const zend_string *const_name);
|
||||
|
||||
#define ZEND_FETCH_ARG_MASK 0x000fffff
|
||||
|
||||
#define ZEND_FE_FETCH_BYREF 1
|
||||
#define ZEND_FE_FETCH_WITH_KEY 2
|
||||
|
||||
#define EXT_TYPE_FREE_ON_RETURN (1<<2)
|
||||
|
||||
#define ZEND_MEMBER_FUNC_CALL 1<<0
|
||||
@ -930,6 +927,9 @@ END_EXTERN_C()
|
||||
/* disable usage of builtin instruction for strlen() */
|
||||
#define ZEND_COMPILE_NO_BUILTIN_STRLEN (1<<6)
|
||||
|
||||
/* disable substitution of persistent constants at compile-time */
|
||||
#define ZEND_COMPILE_NO_PERSISTENT_CONSTANT_SUBSTITUTION (1<<7)
|
||||
|
||||
/* The default value for CG(compiler_options) */
|
||||
#define ZEND_COMPILE_DEFAULT ZEND_COMPILE_HANDLE_OP_ARRAY
|
||||
|
||||
|
@ -1226,7 +1226,7 @@ static zend_always_inline HashTable *zend_get_target_symbol_table(zend_execute_d
|
||||
|
||||
if (EXPECTED(fetch_type == ZEND_FETCH_GLOBAL_LOCK) ||
|
||||
EXPECTED(fetch_type == ZEND_FETCH_GLOBAL)) {
|
||||
ht = &EG(symbol_table).ht;
|
||||
ht = &EG(symbol_table);
|
||||
} else if (EXPECTED(fetch_type == ZEND_FETCH_STATIC)) {
|
||||
ZEND_ASSERT(EX(func)->op_array.static_variables != NULL);
|
||||
ht = EX(func)->op_array.static_variables;
|
||||
@ -1235,7 +1235,7 @@ static zend_always_inline HashTable *zend_get_target_symbol_table(zend_execute_d
|
||||
if (!EX(symbol_table)) {
|
||||
zend_rebuild_symbol_table();
|
||||
}
|
||||
ht = &EX(symbol_table)->ht;
|
||||
ht = EX(symbol_table);
|
||||
}
|
||||
return ht;
|
||||
}
|
||||
@ -1692,6 +1692,14 @@ static inline zend_brk_cont_element* zend_brk_cont(int nest_levels, int array_of
|
||||
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
|
||||
zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
|
||||
}
|
||||
} else if (brk_opline->opcode == ZEND_FE_FREE) {
|
||||
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
|
||||
zval *var = EX_VAR(brk_opline->op1.var);
|
||||
if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
|
||||
zend_hash_iterator_del(Z_FE_ITER_P(var));
|
||||
}
|
||||
zval_ptr_dtor_nogc(var);
|
||||
}
|
||||
}
|
||||
}
|
||||
array_offset = jmp_to->parent;
|
||||
@ -1743,12 +1751,12 @@ ZEND_API void execute_internal(zend_execute_data *execute_data, zval *return_val
|
||||
ZEND_API void zend_clean_and_cache_symbol_table(zend_array *symbol_table) /* {{{ */
|
||||
{
|
||||
if (EG(symtable_cache_ptr) >= EG(symtable_cache_limit)) {
|
||||
zend_array_destroy(&symbol_table->ht);
|
||||
zend_array_destroy(symbol_table);
|
||||
efree_size(symbol_table, sizeof(zend_array));
|
||||
} else {
|
||||
/* clean before putting into the cache, since clean
|
||||
could call dtors, which could use cached hash */
|
||||
zend_symtable_clean(&symbol_table->ht);
|
||||
zend_symtable_clean(symbol_table);
|
||||
*(++EG(symtable_cache_ptr)) = symbol_table;
|
||||
}
|
||||
}
|
||||
|
@ -152,9 +152,7 @@ void init_executor(void) /* {{{ */
|
||||
|
||||
zend_vm_stack_init();
|
||||
|
||||
zend_hash_init(&EG(symbol_table).ht, 64, NULL, ZVAL_PTR_DTOR, 0);
|
||||
GC_REFCOUNT(&EG(symbol_table)) = 1;
|
||||
GC_TYPE_INFO(&EG(symbol_table)) = IS_ARRAY;
|
||||
zend_hash_init(&EG(symbol_table), 64, NULL, ZVAL_PTR_DTOR, 0);
|
||||
EG(valid_symbol_table) = 1;
|
||||
|
||||
zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_activator);
|
||||
@ -183,6 +181,11 @@ void init_executor(void) /* {{{ */
|
||||
|
||||
EG(scope) = NULL;
|
||||
|
||||
EG(ht_iterators_count) = sizeof(EG(ht_iterators_slots)) / sizeof(HashTableIterator);
|
||||
EG(ht_iterators_used) = 0;
|
||||
EG(ht_iterators) = EG(ht_iterators_slots);
|
||||
memset(EG(ht_iterators), 0, sizeof(EG(ht_iterators_slots)));
|
||||
|
||||
EG(active) = 1;
|
||||
}
|
||||
/* }}} */
|
||||
@ -213,14 +216,14 @@ static void zend_unclean_zval_ptr_dtor(zval *zv) /* {{{ */
|
||||
void shutdown_destructors(void) /* {{{ */
|
||||
{
|
||||
if (CG(unclean_shutdown)) {
|
||||
EG(symbol_table).ht.pDestructor = zend_unclean_zval_ptr_dtor;
|
||||
EG(symbol_table).pDestructor = zend_unclean_zval_ptr_dtor;
|
||||
}
|
||||
zend_try {
|
||||
uint32_t symbols;
|
||||
do {
|
||||
symbols = zend_hash_num_elements(&EG(symbol_table).ht);
|
||||
zend_hash_reverse_apply(&EG(symbol_table).ht, (apply_func_t) zval_call_destructor);
|
||||
} while (symbols != zend_hash_num_elements(&EG(symbol_table).ht));
|
||||
symbols = zend_hash_num_elements(&EG(symbol_table));
|
||||
zend_hash_reverse_apply(&EG(symbol_table), (apply_func_t) zval_call_destructor);
|
||||
} while (symbols != zend_hash_num_elements(&EG(symbol_table)));
|
||||
zend_objects_store_call_destructors(&EG(objects_store));
|
||||
} zend_catch {
|
||||
/* if we couldn't destruct cleanly, mark all objects as destructed anyway */
|
||||
@ -254,9 +257,9 @@ void shutdown_executor(void) /* {{{ */
|
||||
zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_deactivator);
|
||||
|
||||
if (CG(unclean_shutdown)) {
|
||||
EG(symbol_table).ht.pDestructor = zend_unclean_zval_ptr_dtor;
|
||||
EG(symbol_table).pDestructor = zend_unclean_zval_ptr_dtor;
|
||||
}
|
||||
zend_hash_graceful_reverse_destroy(&EG(symbol_table).ht);
|
||||
zend_hash_graceful_reverse_destroy(&EG(symbol_table));
|
||||
} zend_end_try();
|
||||
EG(valid_symbol_table) = 0;
|
||||
|
||||
@ -344,7 +347,7 @@ void shutdown_executor(void) /* {{{ */
|
||||
}
|
||||
|
||||
while (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
|
||||
zend_hash_destroy(&(*EG(symtable_cache_ptr))->ht);
|
||||
zend_hash_destroy(*EG(symtable_cache_ptr));
|
||||
FREE_HASHTABLE(*EG(symtable_cache_ptr));
|
||||
EG(symtable_cache_ptr)--;
|
||||
}
|
||||
@ -373,6 +376,11 @@ void shutdown_executor(void) /* {{{ */
|
||||
|
||||
zend_shutdown_fpu();
|
||||
|
||||
EG(ht_iterators_used) = 0;
|
||||
if (EG(ht_iterators) != EG(ht_iterators_slots)) {
|
||||
efree(EG(ht_iterators));
|
||||
}
|
||||
|
||||
EG(active) = 0;
|
||||
}
|
||||
/* }}} */
|
||||
@ -1385,7 +1393,7 @@ void zend_verify_abstract_class(zend_class_entry *ce) /* {{{ */
|
||||
zend_function *func;
|
||||
zend_abstract_info ai;
|
||||
|
||||
if ((ce->ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) && !(ce->ce_flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
|
||||
if ((ce->ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) && !(ce->ce_flags & (ZEND_ACC_TRAIT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))) {
|
||||
memset(&ai, 0, sizeof(ai));
|
||||
|
||||
ZEND_HASH_FOREACH_PTR(&ce->function_table, func) {
|
||||
@ -1407,7 +1415,7 @@ void zend_verify_abstract_class(zend_class_entry *ce) /* {{{ */
|
||||
|
||||
ZEND_API int zend_delete_global_variable(zend_string *name) /* {{{ */
|
||||
{
|
||||
return zend_hash_del_ind(&EG(symbol_table).ht, name);
|
||||
return zend_hash_del_ind(&EG(symbol_table), name);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -1434,17 +1442,14 @@ ZEND_API zend_array *zend_rebuild_symbol_table(void) /* {{{ */
|
||||
symbol_table = ex->symbol_table = *(EG(symtable_cache_ptr)--);
|
||||
} else {
|
||||
symbol_table = ex->symbol_table = emalloc(sizeof(zend_array));
|
||||
GC_REFCOUNT(symbol_table) = 0;
|
||||
GC_TYPE_INFO(symbol_table) = IS_ARRAY;
|
||||
zend_hash_init(&symbol_table->ht, ex->func->op_array.last_var, NULL, ZVAL_PTR_DTOR, 0);
|
||||
zend_hash_init(symbol_table, ex->func->op_array.last_var, NULL, ZVAL_PTR_DTOR, 0);
|
||||
/*printf("Cache miss! Initialized %x\n", EG(active_symbol_table));*/
|
||||
}
|
||||
for (i = 0; i < ex->func->op_array.last_var; i++) {
|
||||
zval zv;
|
||||
|
||||
ZVAL_INDIRECT(&zv, ZEND_CALL_VAR_NUM(ex, i));
|
||||
zend_hash_add_new(&symbol_table->ht,
|
||||
ex->func->op_array.vars[i], &zv);
|
||||
zend_hash_add_new(symbol_table, ex->func->op_array.vars[i], &zv);
|
||||
}
|
||||
return symbol_table;
|
||||
}
|
||||
@ -1454,7 +1459,7 @@ ZEND_API void zend_attach_symbol_table(zend_execute_data *execute_data) /* {{{ *
|
||||
{
|
||||
int i;
|
||||
zend_op_array *op_array = &execute_data->func->op_array;
|
||||
HashTable *ht = &execute_data->symbol_table->ht;
|
||||
HashTable *ht = execute_data->symbol_table;
|
||||
|
||||
/* copy real values from symbol table into CV slots and create
|
||||
INDIRECT references to CV in symbol table */
|
||||
@ -1482,7 +1487,7 @@ ZEND_API void zend_detach_symbol_table(zend_execute_data *execute_data) /* {{{ *
|
||||
{
|
||||
int i;
|
||||
zend_op_array *op_array = &execute_data->func->op_array;
|
||||
HashTable *ht = &execute_data->symbol_table->ht;
|
||||
HashTable *ht = execute_data->symbol_table;
|
||||
|
||||
/* copy real values from CV slots into symbol table */
|
||||
for (i = 0; i < op_array->last_var; i++) {
|
||||
@ -1521,11 +1526,11 @@ ZEND_API int zend_set_local_var(zend_string *name, zval *value, int force) /* {{
|
||||
if (force) {
|
||||
zend_array *symbol_table = zend_rebuild_symbol_table();
|
||||
if (symbol_table) {
|
||||
return zend_hash_update(&symbol_table->ht, name, value) ? SUCCESS : FAILURE;;
|
||||
return zend_hash_update(symbol_table, name, value) ? SUCCESS : FAILURE;;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return (zend_hash_update_ind(&execute_data->symbol_table->ht, name, value) != NULL) ? SUCCESS : FAILURE;
|
||||
return (zend_hash_update_ind(execute_data->symbol_table, name, value) != NULL) ? SUCCESS : FAILURE;
|
||||
}
|
||||
}
|
||||
return FAILURE;
|
||||
@ -1559,11 +1564,11 @@ ZEND_API int zend_set_local_var_str(const char *name, size_t len, zval *value, i
|
||||
if (force) {
|
||||
zend_array *symbol_table = zend_rebuild_symbol_table();
|
||||
if (symbol_table) {
|
||||
return zend_hash_str_update(&symbol_table->ht, name, len, value) ? SUCCESS : FAILURE;;
|
||||
return zend_hash_str_update(symbol_table, name, len, value) ? SUCCESS : FAILURE;;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return (zend_hash_str_update_ind(&execute_data->symbol_table->ht, name, len, value) != NULL) ? SUCCESS : FAILURE;
|
||||
return (zend_hash_str_update_ind(execute_data->symbol_table, name, len, value) != NULL) ? SUCCESS : FAILURE;
|
||||
}
|
||||
}
|
||||
return FAILURE;
|
||||
|
@ -231,9 +231,7 @@ tail_call:
|
||||
for (i = 0; i < n; i++) {
|
||||
if (Z_REFCOUNTED(table[i])) {
|
||||
ref = Z_COUNTED(table[i]);
|
||||
if (GC_TYPE(ref) != IS_ARRAY || (zend_array*)ref != &EG(symbol_table)) {
|
||||
GC_REFCOUNT(ref)++;
|
||||
}
|
||||
GC_REFCOUNT(ref)++;
|
||||
if (GC_GET_COLOR(GC_INFO(ref)) != GC_BLACK) {
|
||||
if (!props && i == n - 1) {
|
||||
goto tail_call;
|
||||
@ -250,14 +248,12 @@ tail_call:
|
||||
}
|
||||
} else if (GC_TYPE(ref) == IS_ARRAY) {
|
||||
if ((zend_array*)ref != &EG(symbol_table)) {
|
||||
ht = &((zend_array*)ref)->ht;
|
||||
ht = (zend_array*)ref;
|
||||
}
|
||||
} else if (GC_TYPE(ref) == IS_REFERENCE) {
|
||||
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
|
||||
ref = Z_COUNTED(((zend_reference*)ref)->val);
|
||||
if (GC_TYPE(ref) != IS_ARRAY || (zend_array*)ref != &EG(symbol_table)) {
|
||||
GC_REFCOUNT(ref)++;
|
||||
}
|
||||
GC_REFCOUNT(ref)++;
|
||||
if (GC_GET_COLOR(GC_INFO(ref)) != GC_BLACK) {
|
||||
goto tail_call;
|
||||
}
|
||||
@ -269,9 +265,7 @@ tail_call:
|
||||
p = ht->arData + idx;
|
||||
if (!Z_REFCOUNTED(p->val)) continue;
|
||||
ref = Z_COUNTED(p->val);
|
||||
if (GC_TYPE(ref) != IS_ARRAY || (zend_array*)ref != &EG(symbol_table)) {
|
||||
GC_REFCOUNT(ref)++;
|
||||
}
|
||||
GC_REFCOUNT(ref)++;
|
||||
if (GC_GET_COLOR(GC_INFO(ref)) != GC_BLACK) {
|
||||
if (idx == ht->nNumUsed-1) {
|
||||
goto tail_call;
|
||||
@ -312,9 +306,7 @@ tail_call:
|
||||
for (i = 0; i < n; i++) {
|
||||
if (Z_REFCOUNTED(table[i])) {
|
||||
ref = Z_COUNTED(table[i]);
|
||||
if (GC_TYPE(ref) != IS_ARRAY || ((zend_array*)ref) != &EG(symbol_table)) {
|
||||
GC_REFCOUNT(ref)--;
|
||||
}
|
||||
GC_REFCOUNT(ref)--;
|
||||
if (!props && i == n - 1) {
|
||||
goto tail_call;
|
||||
} else {
|
||||
@ -331,7 +323,7 @@ tail_call:
|
||||
if (((zend_array*)ref) == &EG(symbol_table)) {
|
||||
GC_SET_BLACK(GC_INFO(ref));
|
||||
} else {
|
||||
ht = &((zend_array*)ref)->ht;
|
||||
ht = (zend_array*)ref;
|
||||
}
|
||||
} else if (GC_TYPE(ref) == IS_REFERENCE) {
|
||||
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
|
||||
@ -341,9 +333,7 @@ tail_call:
|
||||
return;
|
||||
}
|
||||
ref = Z_COUNTED(((zend_reference*)ref)->val);
|
||||
if (GC_TYPE(ref) != IS_ARRAY || (zend_array*)ref != &EG(symbol_table)) {
|
||||
GC_REFCOUNT(ref)--;
|
||||
}
|
||||
GC_REFCOUNT(ref)--;
|
||||
goto tail_call;
|
||||
}
|
||||
return;
|
||||
@ -358,9 +348,7 @@ tail_call:
|
||||
continue;
|
||||
}
|
||||
ref = Z_COUNTED(p->val);
|
||||
if (GC_TYPE(ref) != IS_ARRAY || ((zend_array*)ref) != &EG(symbol_table)) {
|
||||
GC_REFCOUNT(ref)--;
|
||||
}
|
||||
GC_REFCOUNT(ref)--;
|
||||
if (idx == ht->nNumUsed-1) {
|
||||
goto tail_call;
|
||||
} else {
|
||||
@ -428,7 +416,7 @@ tail_call:
|
||||
if ((zend_array*)ref == &EG(symbol_table)) {
|
||||
GC_SET_BLACK(GC_INFO(ref));
|
||||
} else {
|
||||
ht = &((zend_array*)ref)->ht;
|
||||
ht = (zend_array*)ref;
|
||||
}
|
||||
} else if (GC_TYPE(ref) == IS_REFERENCE) {
|
||||
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
|
||||
@ -529,9 +517,7 @@ tail_call:
|
||||
for (i = 0; i < n; i++) {
|
||||
if (Z_REFCOUNTED(table[i])) {
|
||||
ref = Z_COUNTED(table[i]);
|
||||
if (GC_TYPE(ref) != IS_ARRAY || (zend_array*)ref != &EG(symbol_table)) {
|
||||
GC_REFCOUNT(ref)++;
|
||||
}
|
||||
GC_REFCOUNT(ref)++;
|
||||
if (!props && i == n - 1) {
|
||||
goto tail_call;
|
||||
} else {
|
||||
@ -548,13 +534,11 @@ tail_call:
|
||||
ht = props;
|
||||
}
|
||||
} else if (GC_TYPE(ref) == IS_ARRAY) {
|
||||
ht = &((zend_array*)ref)->ht;
|
||||
ht = (zend_array*)ref;
|
||||
} else if (GC_TYPE(ref) == IS_REFERENCE) {
|
||||
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
|
||||
ref = Z_COUNTED(((zend_reference*)ref)->val);
|
||||
if (GC_TYPE(ref) != IS_ARRAY || (zend_array*)ref != &EG(symbol_table)) {
|
||||
GC_REFCOUNT(ref)++;
|
||||
}
|
||||
GC_REFCOUNT(ref)++;
|
||||
goto tail_call;
|
||||
}
|
||||
return count;
|
||||
@ -571,9 +555,7 @@ tail_call:
|
||||
continue;
|
||||
}
|
||||
ref = Z_COUNTED(p->val);
|
||||
if (GC_TYPE(ref) != IS_ARRAY || (zend_array*)ref != &EG(symbol_table)) {
|
||||
GC_REFCOUNT(ref)++;
|
||||
}
|
||||
GC_REFCOUNT(ref)++;
|
||||
if (idx == ht->nNumUsed-1) {
|
||||
goto tail_call;
|
||||
} else {
|
||||
@ -681,7 +663,7 @@ tail_call:
|
||||
ht = props;
|
||||
}
|
||||
} else if (GC_TYPE(ref) == IS_ARRAY) {
|
||||
ht = &((zend_array*)ref)->ht;
|
||||
ht = (zend_array*)ref;
|
||||
} else if (GC_TYPE(ref) == IS_REFERENCE) {
|
||||
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
|
||||
ref = Z_COUNTED(((zend_reference*)ref)->val);
|
||||
@ -802,8 +784,9 @@ ZEND_API int zend_gc_collect_cycles(void)
|
||||
} else if (GC_TYPE(p) == IS_ARRAY) {
|
||||
zend_array *arr = (zend_array*)p;
|
||||
|
||||
GC_REFCOUNT(arr) = 0;
|
||||
GC_TYPE(arr) = IS_NULL;
|
||||
zend_hash_destroy(&arr->ht);
|
||||
zend_hash_destroy(arr);
|
||||
}
|
||||
current = GC_G(next_to_free);
|
||||
}
|
||||
|
@ -60,6 +60,12 @@ static void zend_generator_cleanup_unfinished_execution(zend_generator *generato
|
||||
if (brk_opline->opcode == ZEND_FREE) {
|
||||
zval *var = EX_VAR(brk_opline->op1.var);
|
||||
zval_ptr_dtor_nogc(var);
|
||||
} else if (brk_opline->opcode == ZEND_FE_FREE) {
|
||||
zval *var = EX_VAR(brk_opline->op1.var);
|
||||
if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
|
||||
zend_hash_iterator_del(Z_FE_ITER_P(var));
|
||||
}
|
||||
zval_ptr_dtor_nogc(var);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -226,6 +226,11 @@ struct _zend_executor_globals {
|
||||
zend_bool active;
|
||||
zend_bool valid_symbol_table;
|
||||
|
||||
uint32_t ht_iterators_count; /* number of allocatd slots */
|
||||
uint32_t ht_iterators_used; /* number of used slots */
|
||||
HashTableIterator *ht_iterators;
|
||||
HashTableIterator ht_iterators_slots[16];
|
||||
|
||||
void *saved_fpu_cw_ptr;
|
||||
#if XPFPA_HAVE_CW
|
||||
XPFPA_CW_DATATYPE saved_fpu_cw;
|
||||
|
330
Zend/zend_hash.c
330
Zend/zend_hash.c
@ -23,6 +23,13 @@
|
||||
#include "zend_globals.h"
|
||||
#include "zend_variables.h"
|
||||
|
||||
#define HT_DEBUG 0
|
||||
#if HT_DEBUG
|
||||
# define HT_ASSERT(c) ZEND_ASSERT(c)
|
||||
#else
|
||||
# define HT_ASSERT(c)
|
||||
#endif
|
||||
|
||||
#if ZEND_DEBUG
|
||||
/*
|
||||
#define HASH_MASK_CONSISTENCY 0x60
|
||||
@ -82,42 +89,26 @@ static void _zend_is_inconsistent(const HashTable *ht, const char *file, int lin
|
||||
|
||||
static void zend_hash_do_resize(HashTable *ht);
|
||||
|
||||
#define CHECK_INIT(ht, packed) do { \
|
||||
if (UNEXPECTED(!((ht)->u.flags & HASH_FLAG_INITIALIZED))) { \
|
||||
if (packed) { \
|
||||
(ht)->u.flags |= HASH_FLAG_INITIALIZED | HASH_FLAG_PACKED; \
|
||||
(ht)->arData = (Bucket *) safe_pemalloc((ht)->nTableSize, sizeof(Bucket), 0, (ht)->u.flags & HASH_FLAG_PERSISTENT); \
|
||||
} else { \
|
||||
(ht)->u.flags |= HASH_FLAG_INITIALIZED; \
|
||||
(ht)->nTableMask = (ht)->nTableSize - 1; \
|
||||
(ht)->arData = (Bucket *) safe_pemalloc((ht)->nTableSize, sizeof(Bucket) + sizeof(uint32_t), 0, (ht)->u.flags & HASH_FLAG_PERSISTENT); \
|
||||
(ht)->arHash = (uint32_t*)((ht)->arData + (ht)->nTableSize); \
|
||||
memset((ht)->arHash, INVALID_IDX, (ht)->nTableSize * sizeof(uint32_t)); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static const uint32_t uninitialized_bucket = {INVALID_IDX};
|
||||
|
||||
ZEND_API void _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC)
|
||||
static uint32_t zend_always_inline zend_hash_check_size(uint32_t nSize)
|
||||
{
|
||||
#if defined(ZEND_WIN32)
|
||||
unsigned long index;
|
||||
#endif
|
||||
|
||||
/* Use big enough power of 2 */
|
||||
/* size should be between 8 and 0x80000000 */
|
||||
nSize = (nSize <= 8 ? 8 : (nSize >= 0x80000000 ? 0x80000000 : nSize));
|
||||
/* size should be between HT_MIN_SIZE and HT_MAX_SIZE */
|
||||
nSize = (nSize <= HT_MIN_SIZE ? HT_MIN_SIZE : (nSize >= HT_MAX_SIZE ? HT_MAX_SIZE : nSize));
|
||||
|
||||
#if defined(ZEND_WIN32)
|
||||
if (BitScanReverse(&index, nSize - 1)) {
|
||||
ht->nTableSize = 0x2 << ((31 - index) ^ 0x1f);
|
||||
return 0x2 << ((31 - index) ^ 0x1f);
|
||||
} else {
|
||||
/* nSize is ensured to be in the valid range, fall back to it
|
||||
rather than using an undefined bis scan result. */
|
||||
ht->nTableSize = nSize;
|
||||
return nSize;
|
||||
}
|
||||
#elif defined(__GNUC__)
|
||||
ht->nTableSize = 0x2 << (__builtin_clz(nSize - 1) ^ 0x1f);
|
||||
return 0x2 << (__builtin_clz(nSize - 1) ^ 0x1f);
|
||||
#else
|
||||
nSize -= 1;
|
||||
nSize |= (nSize >> 1);
|
||||
@ -125,9 +116,37 @@ ZEND_API void _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_func_t pDestru
|
||||
nSize |= (nSize >> 4);
|
||||
nSize |= (nSize >> 8);
|
||||
nSize |= (nSize >> 16);
|
||||
ht->nTableSize = nSize + 1;
|
||||
return nSize + 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void zend_always_inline zend_hash_check_init(HashTable *ht, int packed)
|
||||
{
|
||||
HT_ASSERT(GC_REFCOUNT(ht) == 1);
|
||||
if (UNEXPECTED(!((ht)->u.flags & HASH_FLAG_INITIALIZED))) {
|
||||
if (packed) {
|
||||
(ht)->u.flags |= HASH_FLAG_INITIALIZED | HASH_FLAG_PACKED;
|
||||
(ht)->arData = (Bucket *) pemalloc((ht)->nTableSize * sizeof(Bucket), (ht)->u.flags & HASH_FLAG_PERSISTENT);
|
||||
} else {
|
||||
(ht)->u.flags |= HASH_FLAG_INITIALIZED;
|
||||
(ht)->nTableMask = (ht)->nTableSize - 1;
|
||||
(ht)->arData = (Bucket *) pemalloc((ht)->nTableSize * (sizeof(Bucket) + sizeof(uint32_t)), (ht)->u.flags & HASH_FLAG_PERSISTENT);
|
||||
(ht)->arHash = (uint32_t*)((ht)->arData + (ht)->nTableSize);
|
||||
memset((ht)->arHash, INVALID_IDX, (ht)->nTableSize * sizeof(uint32_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define CHECK_INIT(ht, packed) \
|
||||
zend_hash_check_init(ht, packed)
|
||||
|
||||
static const uint32_t uninitialized_bucket = {INVALID_IDX};
|
||||
|
||||
ZEND_API void _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC)
|
||||
{
|
||||
GC_REFCOUNT(ht) = 1;
|
||||
GC_TYPE_INFO(ht) = IS_ARRAY;
|
||||
ht->nTableSize = zend_hash_check_size(nSize);
|
||||
ht->nTableMask = 0;
|
||||
ht->nNumUsed = 0;
|
||||
ht->nNumOfElements = 0;
|
||||
@ -141,9 +160,13 @@ ZEND_API void _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_func_t pDestru
|
||||
|
||||
static void zend_hash_packed_grow(HashTable *ht)
|
||||
{
|
||||
HT_ASSERT(GC_REFCOUNT(ht) == 1);
|
||||
if (ht->nTableSize >= HT_MAX_SIZE) {
|
||||
zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket), sizeof(Bucket));
|
||||
}
|
||||
HANDLE_BLOCK_INTERRUPTIONS();
|
||||
ht->arData = (Bucket *) safe_perealloc(ht->arData, (ht->nTableSize << 1), sizeof(Bucket), 0, ht->u.flags & HASH_FLAG_PERSISTENT);
|
||||
ht->nTableSize = (ht->nTableSize << 1);
|
||||
ht->nTableSize += ht->nTableSize;
|
||||
ht->arData = (Bucket *) perealloc(ht->arData, ht->nTableSize * sizeof(Bucket), ht->u.flags & HASH_FLAG_PERSISTENT);
|
||||
HANDLE_UNBLOCK_INTERRUPTIONS();
|
||||
}
|
||||
|
||||
@ -151,15 +174,17 @@ ZEND_API void zend_hash_real_init(HashTable *ht, zend_bool packed)
|
||||
{
|
||||
IS_CONSISTENT(ht);
|
||||
|
||||
HT_ASSERT(GC_REFCOUNT(ht) == 1);
|
||||
CHECK_INIT(ht, packed);
|
||||
}
|
||||
|
||||
ZEND_API void zend_hash_packed_to_hash(HashTable *ht)
|
||||
{
|
||||
HT_ASSERT(GC_REFCOUNT(ht) == 1);
|
||||
HANDLE_BLOCK_INTERRUPTIONS();
|
||||
ht->u.flags &= ~HASH_FLAG_PACKED;
|
||||
ht->nTableMask = ht->nTableSize - 1;
|
||||
ht->arData = (Bucket *) safe_perealloc(ht->arData, ht->nTableSize, sizeof(Bucket) + sizeof(uint32_t), 0, ht->u.flags & HASH_FLAG_PERSISTENT);
|
||||
ht->arData = (Bucket *) perealloc(ht->arData, ht->nTableSize * (sizeof(Bucket) + sizeof(uint32_t)), ht->u.flags & HASH_FLAG_PERSISTENT);
|
||||
ht->arHash = (uint32_t*)(ht->arData + ht->nTableSize);
|
||||
zend_hash_rehash(ht);
|
||||
HANDLE_UNBLOCK_INTERRUPTIONS();
|
||||
@ -167,6 +192,7 @@ ZEND_API void zend_hash_packed_to_hash(HashTable *ht)
|
||||
|
||||
ZEND_API void zend_hash_to_packed(HashTable *ht)
|
||||
{
|
||||
HT_ASSERT(GC_REFCOUNT(ht) == 1);
|
||||
HANDLE_BLOCK_INTERRUPTIONS();
|
||||
ht->u.flags |= HASH_FLAG_PACKED;
|
||||
ht->nTableMask = 0;
|
||||
@ -193,6 +219,139 @@ ZEND_API void zend_hash_set_apply_protection(HashTable *ht, zend_bool bApplyProt
|
||||
}
|
||||
}
|
||||
|
||||
ZEND_API uint32_t zend_hash_iterator_add(HashTable *ht, HashPosition pos)
|
||||
{
|
||||
HashTableIterator *iter = EG(ht_iterators);
|
||||
HashTableIterator *end = iter + EG(ht_iterators_count);
|
||||
uint32_t idx;
|
||||
|
||||
if (EXPECTED(ht->u.v.nIteratorsCount != 255)) {
|
||||
ht->u.v.nIteratorsCount++;
|
||||
}
|
||||
while (iter != end) {
|
||||
if (iter->ht == NULL) {
|
||||
iter->ht = ht;
|
||||
iter->pos = pos;
|
||||
idx = iter - EG(ht_iterators);
|
||||
if (idx + 1 > EG(ht_iterators_used)) {
|
||||
EG(ht_iterators_used) = idx + 1;
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
if (EG(ht_iterators) == EG(ht_iterators_slots)) {
|
||||
EG(ht_iterators) = emalloc(sizeof(HashTableIterator) * (EG(ht_iterators_count) + 8));
|
||||
memcpy(EG(ht_iterators), EG(ht_iterators_slots), sizeof(HashTableIterator) * EG(ht_iterators_count));
|
||||
} else {
|
||||
EG(ht_iterators) = erealloc(EG(ht_iterators), sizeof(HashTableIterator) * (EG(ht_iterators_count) + 8));
|
||||
}
|
||||
iter = EG(ht_iterators) + EG(ht_iterators_count);
|
||||
EG(ht_iterators_count) += 8;
|
||||
iter->ht = ht;
|
||||
iter->pos = pos;
|
||||
memset(iter + 1, 0, sizeof(HashTableIterator) * 7);
|
||||
idx = iter - EG(ht_iterators);
|
||||
EG(ht_iterators_used) = idx + 1;
|
||||
return idx;
|
||||
}
|
||||
|
||||
ZEND_API HashPosition zend_hash_iterator_pos(uint32_t idx, HashTable *ht)
|
||||
{
|
||||
HashTableIterator *iter = EG(ht_iterators) + idx;
|
||||
|
||||
ZEND_ASSERT(idx != (uint32_t)-1);
|
||||
if (iter->pos == INVALID_IDX) {
|
||||
return INVALID_IDX;
|
||||
} else if (UNEXPECTED(iter->ht != ht)) {
|
||||
if (EXPECTED(iter->ht) && EXPECTED(iter->ht->u.v.nIteratorsCount != 255)) {
|
||||
iter->ht->u.v.nIteratorsCount--;
|
||||
}
|
||||
if (EXPECTED(ht->u.v.nIteratorsCount != 255)) {
|
||||
ht->u.v.nIteratorsCount++;
|
||||
}
|
||||
iter->ht = ht;
|
||||
iter->pos = ht->nInternalPointer;
|
||||
}
|
||||
return iter->pos;
|
||||
}
|
||||
|
||||
ZEND_API void zend_hash_iterator_del(uint32_t idx)
|
||||
{
|
||||
HashTableIterator *iter = EG(ht_iterators) + idx;
|
||||
|
||||
ZEND_ASSERT(idx != (uint32_t)-1);
|
||||
|
||||
if (EXPECTED(iter->ht) && EXPECTED(iter->ht->u.v.nIteratorsCount != 255)) {
|
||||
iter->ht->u.v.nIteratorsCount--;
|
||||
}
|
||||
iter->ht = NULL;
|
||||
|
||||
if (idx == EG(ht_iterators_used) - 1) {
|
||||
while (idx > 0 && EG(ht_iterators)[idx - 1].ht == NULL) {
|
||||
idx--;
|
||||
}
|
||||
EG(ht_iterators_used) = idx;
|
||||
}
|
||||
}
|
||||
|
||||
static zend_never_inline void _zend_hash_iterators_remove(HashTable *ht)
|
||||
{
|
||||
HashTableIterator *iter = EG(ht_iterators);
|
||||
HashTableIterator *end = iter + EG(ht_iterators_used);
|
||||
uint32_t idx;
|
||||
|
||||
while (iter != end) {
|
||||
if (iter->ht == ht) {
|
||||
iter->ht = NULL;
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
|
||||
idx = EG(ht_iterators_used);
|
||||
while (idx > 0 && EG(ht_iterators)[idx - 1].ht == NULL) {
|
||||
idx--;
|
||||
}
|
||||
EG(ht_iterators_used) = idx;
|
||||
}
|
||||
|
||||
static zend_always_inline void zend_hash_iterators_remove(HashTable *ht)
|
||||
{
|
||||
if (UNEXPECTED(ht->u.v.nIteratorsCount)) {
|
||||
_zend_hash_iterators_remove(ht);
|
||||
}
|
||||
}
|
||||
|
||||
ZEND_API HashPosition zend_hash_iterators_lower_pos(HashTable *ht, HashPosition start)
|
||||
{
|
||||
HashTableIterator *iter = EG(ht_iterators);
|
||||
HashTableIterator *end = iter + EG(ht_iterators_used);
|
||||
HashPosition res = INVALID_IDX;
|
||||
|
||||
while (iter != end) {
|
||||
if (iter->ht == ht) {
|
||||
if (iter->pos >= start && iter->pos < res) {
|
||||
res = iter->pos;
|
||||
}
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
ZEND_API void _zend_hash_iterators_update(HashTable *ht, HashPosition from, HashPosition to)
|
||||
{
|
||||
HashTableIterator *iter = EG(ht_iterators);
|
||||
HashTableIterator *end = iter + EG(ht_iterators_used);
|
||||
|
||||
while (iter != end) {
|
||||
if (iter->ht == ht && iter->pos == from) {
|
||||
iter->pos = to;
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
static zend_always_inline Bucket *zend_hash_find_bucket(const HashTable *ht, zend_string *key)
|
||||
{
|
||||
zend_ulong h;
|
||||
@ -266,6 +425,7 @@ static zend_always_inline zval *_zend_hash_add_or_update_i(HashTable *ht, zend_s
|
||||
Bucket *p;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
HT_ASSERT(GC_REFCOUNT(ht) == 1);
|
||||
|
||||
if (UNEXPECTED(!(ht->u.flags & HASH_FLAG_INITIALIZED))) {
|
||||
CHECK_INIT(ht, 0);
|
||||
@ -305,6 +465,7 @@ add_to_hash:
|
||||
if (ht->nInternalPointer == INVALID_IDX) {
|
||||
ht->nInternalPointer = idx;
|
||||
}
|
||||
zend_hash_iterators_update(ht, INVALID_IDX, idx);
|
||||
p = ht->arData + idx;
|
||||
p->h = h = zend_string_hash_val(key);
|
||||
p->key = key;
|
||||
@ -417,6 +578,7 @@ static zend_always_inline zval *_zend_hash_index_add_or_update_i(HashTable *ht,
|
||||
Bucket *p;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
HT_ASSERT(GC_REFCOUNT(ht) == 1);
|
||||
|
||||
if (UNEXPECTED(!(ht->u.flags & HASH_FLAG_INITIALIZED))) {
|
||||
CHECK_INIT(ht, h < ht->nTableSize);
|
||||
@ -472,6 +634,7 @@ add_to_packed:
|
||||
if (ht->nInternalPointer == INVALID_IDX) {
|
||||
ht->nInternalPointer = h;
|
||||
}
|
||||
zend_hash_iterators_update(ht, INVALID_IDX, h);
|
||||
if ((zend_long)h >= (zend_long)ht->nNextFreeElement) {
|
||||
ht->nNextFreeElement = h < ZEND_LONG_MAX ? h + 1 : ZEND_LONG_MAX;
|
||||
}
|
||||
@ -514,6 +677,7 @@ add_to_hash:
|
||||
if (ht->nInternalPointer == INVALID_IDX) {
|
||||
ht->nInternalPointer = idx;
|
||||
}
|
||||
zend_hash_iterators_update(ht, INVALID_IDX, idx);
|
||||
if ((zend_long)h >= (zend_long)ht->nNextFreeElement) {
|
||||
ht->nNextFreeElement = h < ZEND_LONG_MAX ? h + 1 : ZEND_LONG_MAX;
|
||||
}
|
||||
@ -563,19 +727,22 @@ static void zend_hash_do_resize(HashTable *ht)
|
||||
{
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
HT_ASSERT(GC_REFCOUNT(ht) == 1);
|
||||
|
||||
if (ht->nNumUsed > ht->nNumOfElements) {
|
||||
HANDLE_BLOCK_INTERRUPTIONS();
|
||||
zend_hash_rehash(ht);
|
||||
HANDLE_UNBLOCK_INTERRUPTIONS();
|
||||
} else if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */
|
||||
} else if (ht->nTableSize < HT_MAX_SIZE) { /* Let's double the table size */
|
||||
HANDLE_BLOCK_INTERRUPTIONS();
|
||||
ht->arData = (Bucket *) safe_perealloc(ht->arData, (ht->nTableSize << 1), sizeof(Bucket) + sizeof(uint32_t), 0, ht->u.flags & HASH_FLAG_PERSISTENT);
|
||||
ht->arHash = (uint32_t*)(ht->arData + (ht->nTableSize << 1));
|
||||
ht->nTableSize = (ht->nTableSize << 1);
|
||||
ht->nTableSize += ht->nTableSize;
|
||||
ht->arData = (Bucket *) perealloc(ht->arData, ht->nTableSize * (sizeof(Bucket) + sizeof(uint32_t)), ht->u.flags & HASH_FLAG_PERSISTENT);
|
||||
ht->arHash = (uint32_t*)(ht->arData + ht->nTableSize);
|
||||
ht->nTableMask = ht->nTableSize - 1;
|
||||
zend_hash_rehash(ht);
|
||||
HANDLE_UNBLOCK_INTERRUPTIONS();
|
||||
} else {
|
||||
zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket) + sizeof(uint32_t), sizeof(Bucket));
|
||||
}
|
||||
}
|
||||
|
||||
@ -594,19 +761,42 @@ ZEND_API int zend_hash_rehash(HashTable *ht)
|
||||
}
|
||||
|
||||
memset(ht->arHash, INVALID_IDX, ht->nTableSize * sizeof(uint32_t));
|
||||
for (i = 0, j = 0; i < ht->nNumUsed; i++) {
|
||||
p = ht->arData + i;
|
||||
if (Z_TYPE(p->val) == IS_UNDEF) continue;
|
||||
if (i != j) {
|
||||
ht->arData[j] = ht->arData[i];
|
||||
if (ht->nInternalPointer == i) {
|
||||
ht->nInternalPointer = j;
|
||||
if (EXPECTED(ht->u.v.nIteratorsCount == 0)) {
|
||||
for (i = 0, j = 0; i < ht->nNumUsed; i++) {
|
||||
p = ht->arData + i;
|
||||
if (Z_TYPE(p->val) == IS_UNDEF) continue;
|
||||
if (i != j) {
|
||||
ht->arData[j] = ht->arData[i];
|
||||
if (ht->nInternalPointer == i) {
|
||||
ht->nInternalPointer = j;
|
||||
}
|
||||
}
|
||||
nIndex = ht->arData[j].h & ht->nTableMask;
|
||||
Z_NEXT(ht->arData[j].val) = ht->arHash[nIndex];
|
||||
ht->arHash[nIndex] = j;
|
||||
j++;
|
||||
}
|
||||
} else {
|
||||
uint32_t iter_pos = zend_hash_iterators_lower_pos(ht, 0);
|
||||
|
||||
for (i = 0, j = 0; i < ht->nNumUsed; i++) {
|
||||
p = ht->arData + i;
|
||||
if (Z_TYPE(p->val) == IS_UNDEF) continue;
|
||||
if (i != j) {
|
||||
ht->arData[j] = ht->arData[i];
|
||||
if (ht->nInternalPointer == i) {
|
||||
ht->nInternalPointer = j;
|
||||
}
|
||||
if (i == iter_pos) {
|
||||
zend_hash_iterators_update(ht, i, j);
|
||||
iter_pos = zend_hash_iterators_lower_pos(ht, iter_pos + 1);
|
||||
}
|
||||
}
|
||||
nIndex = ht->arData[j].h & ht->nTableMask;
|
||||
Z_NEXT(ht->arData[j].val) = ht->arHash[nIndex];
|
||||
ht->arHash[nIndex] = j;
|
||||
j++;
|
||||
}
|
||||
nIndex = ht->arData[j].h & ht->nTableMask;
|
||||
Z_NEXT(ht->arData[j].val) = ht->arHash[nIndex];
|
||||
ht->arHash[nIndex] = j;
|
||||
j++;
|
||||
}
|
||||
ht->nNumUsed = j;
|
||||
return SUCCESS;
|
||||
@ -628,17 +818,22 @@ static zend_always_inline void _zend_hash_del_el_ex(HashTable *ht, uint32_t idx,
|
||||
} while (ht->nNumUsed > 0 && (Z_TYPE(ht->arData[ht->nNumUsed-1].val) == IS_UNDEF));
|
||||
}
|
||||
ht->nNumOfElements--;
|
||||
if (ht->nInternalPointer == idx) {
|
||||
if (ht->nInternalPointer == idx || UNEXPECTED(ht->u.v.nIteratorsCount)) {
|
||||
uint32_t new_idx = idx;
|
||||
|
||||
while (1) {
|
||||
idx++;
|
||||
if (idx >= ht->nNumUsed) {
|
||||
ht->nInternalPointer = INVALID_IDX;
|
||||
new_idx++;
|
||||
if (new_idx >= ht->nNumUsed) {
|
||||
new_idx = INVALID_IDX;
|
||||
break;
|
||||
} else if (Z_TYPE(ht->arData[idx].val) != IS_UNDEF) {
|
||||
ht->nInternalPointer = idx;
|
||||
} else if (Z_TYPE(ht->arData[new_idx].val) != IS_UNDEF) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ht->nInternalPointer == idx) {
|
||||
ht->nInternalPointer = new_idx;
|
||||
}
|
||||
zend_hash_iterators_update(ht, idx, new_idx);
|
||||
}
|
||||
if (p->key) {
|
||||
zend_string_release(p->key);
|
||||
@ -683,6 +878,7 @@ ZEND_API int zend_hash_del(HashTable *ht, zend_string *key)
|
||||
Bucket *prev = NULL;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
HT_ASSERT(GC_REFCOUNT(ht) == 1);
|
||||
|
||||
h = zend_string_hash_val(key);
|
||||
nIndex = h & ht->nTableMask;
|
||||
@ -713,6 +909,7 @@ ZEND_API int zend_hash_del_ind(HashTable *ht, zend_string *key)
|
||||
Bucket *prev = NULL;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
HT_ASSERT(GC_REFCOUNT(ht) == 1);
|
||||
|
||||
h = zend_string_hash_val(key);
|
||||
nIndex = h & ht->nTableMask;
|
||||
@ -756,6 +953,7 @@ ZEND_API int zend_hash_str_del(HashTable *ht, const char *str, size_t len)
|
||||
Bucket *prev = NULL;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
HT_ASSERT(GC_REFCOUNT(ht) == 1);
|
||||
|
||||
h = zend_inline_hash_func(str, len);
|
||||
nIndex = h & ht->nTableMask;
|
||||
@ -798,6 +996,7 @@ ZEND_API int zend_hash_str_del_ind(HashTable *ht, const char *str, size_t len)
|
||||
Bucket *prev = NULL;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
HT_ASSERT(GC_REFCOUNT(ht) == 1);
|
||||
|
||||
h = zend_inline_hash_func(str, len);
|
||||
nIndex = h & ht->nTableMask;
|
||||
@ -826,6 +1025,7 @@ ZEND_API int zend_hash_index_del(HashTable *ht, zend_ulong h)
|
||||
Bucket *prev = NULL;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
HT_ASSERT(GC_REFCOUNT(ht) == 1);
|
||||
|
||||
if (ht->u.flags & HASH_FLAG_PACKED) {
|
||||
if (h < ht->nNumUsed) {
|
||||
@ -857,6 +1057,7 @@ ZEND_API void zend_hash_destroy(HashTable *ht)
|
||||
Bucket *p, *end;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
HT_ASSERT(GC_REFCOUNT(ht) <= 1);
|
||||
|
||||
if (ht->nNumUsed) {
|
||||
p = ht->arData;
|
||||
@ -893,6 +1094,7 @@ ZEND_API void zend_hash_destroy(HashTable *ht)
|
||||
} while (++p != end);
|
||||
}
|
||||
}
|
||||
zend_hash_iterators_remove(ht);
|
||||
} else if (EXPECTED(!(ht->u.flags & HASH_FLAG_INITIALIZED))) {
|
||||
return;
|
||||
}
|
||||
@ -904,6 +1106,7 @@ ZEND_API void zend_array_destroy(HashTable *ht)
|
||||
Bucket *p, *end;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
HT_ASSERT(GC_REFCOUNT(ht) <= 1);
|
||||
|
||||
if (ht->nNumUsed) {
|
||||
|
||||
@ -933,7 +1136,7 @@ ZEND_API void zend_array_destroy(HashTable *ht)
|
||||
}
|
||||
} while (++p != end);
|
||||
}
|
||||
|
||||
zend_hash_iterators_remove(ht);
|
||||
SET_INCONSISTENT(HT_DESTROYED);
|
||||
} else if (EXPECTED(!(ht->u.flags & HASH_FLAG_INITIALIZED))) {
|
||||
return;
|
||||
@ -946,6 +1149,7 @@ ZEND_API void zend_hash_clean(HashTable *ht)
|
||||
Bucket *p, *end;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
HT_ASSERT(GC_REFCOUNT(ht) == 1);
|
||||
|
||||
if (ht->nNumUsed) {
|
||||
p = ht->arData;
|
||||
@ -993,6 +1197,7 @@ ZEND_API void zend_symtable_clean(HashTable *ht)
|
||||
Bucket *p, *end;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
HT_ASSERT(GC_REFCOUNT(ht) == 1);
|
||||
|
||||
if (ht->nNumUsed) {
|
||||
p = ht->arData;
|
||||
@ -1021,6 +1226,7 @@ ZEND_API void zend_hash_graceful_destroy(HashTable *ht)
|
||||
Bucket *p;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
HT_ASSERT(GC_REFCOUNT(ht) == 1);
|
||||
|
||||
for (idx = 0; idx < ht->nNumUsed; idx++) {
|
||||
p = ht->arData + idx;
|
||||
@ -1040,6 +1246,7 @@ ZEND_API void zend_hash_graceful_reverse_destroy(HashTable *ht)
|
||||
Bucket *p;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
HT_ASSERT(GC_REFCOUNT(ht) == 1);
|
||||
|
||||
idx = ht->nNumUsed;
|
||||
while (idx > 0) {
|
||||
@ -1072,6 +1279,7 @@ ZEND_API void zend_hash_apply(HashTable *ht, apply_func_t apply_func)
|
||||
int result;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
HT_ASSERT(GC_REFCOUNT(ht) == 1);
|
||||
|
||||
HASH_PROTECT_RECURSION(ht);
|
||||
for (idx = 0; idx < ht->nNumUsed; idx++) {
|
||||
@ -1098,6 +1306,7 @@ ZEND_API void zend_hash_apply_with_argument(HashTable *ht, apply_func_arg_t appl
|
||||
int result;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
HT_ASSERT(GC_REFCOUNT(ht) == 1);
|
||||
|
||||
HASH_PROTECT_RECURSION(ht);
|
||||
for (idx = 0; idx < ht->nNumUsed; idx++) {
|
||||
@ -1126,6 +1335,7 @@ ZEND_API void zend_hash_apply_with_arguments(HashTable *ht, apply_func_args_t ap
|
||||
int result;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
HT_ASSERT(GC_REFCOUNT(ht) == 1);
|
||||
|
||||
HASH_PROTECT_RECURSION(ht);
|
||||
|
||||
@ -1159,6 +1369,7 @@ ZEND_API void zend_hash_reverse_apply(HashTable *ht, apply_func_t apply_func)
|
||||
int result;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
HT_ASSERT(GC_REFCOUNT(ht) == 1);
|
||||
|
||||
HASH_PROTECT_RECURSION(ht);
|
||||
idx = ht->nNumUsed;
|
||||
@ -1189,6 +1400,7 @@ ZEND_API void zend_hash_copy(HashTable *target, HashTable *source, copy_ctor_fun
|
||||
|
||||
IS_CONSISTENT(source);
|
||||
IS_CONSISTENT(target);
|
||||
HT_ASSERT(GC_REFCOUNT(target) == 1);
|
||||
|
||||
setTargetPointer = (target->nInternalPointer == INVALID_IDX);
|
||||
for (idx = 0; idx < source->nNumUsed; idx++) {
|
||||
@ -1225,15 +1437,20 @@ ZEND_API void zend_hash_copy(HashTable *target, HashTable *source, copy_ctor_fun
|
||||
}
|
||||
|
||||
|
||||
ZEND_API void zend_array_dup(HashTable *target, HashTable *source)
|
||||
ZEND_API HashTable *zend_array_dup(HashTable *source)
|
||||
{
|
||||
uint32_t idx, target_idx;
|
||||
uint32_t nIndex;
|
||||
Bucket *p, *q;
|
||||
zval *data;
|
||||
HashTable *target;
|
||||
|
||||
IS_CONSISTENT(source);
|
||||
|
||||
ALLOC_HASHTABLE(target);
|
||||
GC_REFCOUNT(target) = 1;
|
||||
GC_TYPE_INFO(target) = IS_ARRAY;
|
||||
|
||||
target->nTableMask = source->nTableMask;
|
||||
target->nTableSize = source->nTableSize;
|
||||
target->pDestructor = source->pDestructor;
|
||||
@ -1246,7 +1463,7 @@ ZEND_API void zend_array_dup(HashTable *target, HashTable *source)
|
||||
target->nNumUsed = source->nNumUsed;
|
||||
target->nNumOfElements = source->nNumOfElements;
|
||||
target->nNextFreeElement = source->nNextFreeElement;
|
||||
target->arData = (Bucket *) safe_pemalloc(target->nTableSize, sizeof(Bucket), 0, 0);
|
||||
target->arData = (Bucket *) pemalloc(target->nTableSize * sizeof(Bucket), 0);
|
||||
target->arHash = (uint32_t*)&uninitialized_bucket;
|
||||
target->nInternalPointer = source->nInternalPointer;
|
||||
|
||||
@ -1289,7 +1506,7 @@ ZEND_API void zend_array_dup(HashTable *target, HashTable *source)
|
||||
}
|
||||
} else {
|
||||
target->nNextFreeElement = source->nNextFreeElement;
|
||||
target->arData = (Bucket *) safe_pemalloc(target->nTableSize, sizeof(Bucket) + sizeof(uint32_t), 0, 0);
|
||||
target->arData = (Bucket *) pemalloc(target->nTableSize * (sizeof(Bucket) + sizeof(uint32_t)), 0);
|
||||
target->arHash = (uint32_t*)(target->arData + target->nTableSize);
|
||||
memset(target->arHash, INVALID_IDX, target->nTableSize * sizeof(uint32_t));
|
||||
|
||||
@ -1343,6 +1560,7 @@ ZEND_API void zend_array_dup(HashTable *target, HashTable *source)
|
||||
target->arData = NULL;
|
||||
target->arHash = (uint32_t*)&uninitialized_bucket;
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
|
||||
@ -1355,6 +1573,7 @@ ZEND_API void _zend_hash_merge(HashTable *target, HashTable *source, copy_ctor_f
|
||||
|
||||
IS_CONSISTENT(source);
|
||||
IS_CONSISTENT(target);
|
||||
HT_ASSERT(GC_REFCOUNT(target) == 1);
|
||||
|
||||
for (idx = 0; idx < source->nNumUsed; idx++) {
|
||||
p = source->arData + idx;
|
||||
@ -1401,6 +1620,7 @@ ZEND_API void zend_hash_merge_ex(HashTable *target, HashTable *source, copy_ctor
|
||||
|
||||
IS_CONSISTENT(source);
|
||||
IS_CONSISTENT(target);
|
||||
HT_ASSERT(GC_REFCOUNT(target) == 1);
|
||||
|
||||
for (idx = 0; idx < source->nNumUsed; idx++) {
|
||||
p = source->arData + idx;
|
||||
@ -1516,6 +1736,8 @@ ZEND_API void zend_hash_internal_pointer_reset_ex(HashTable *ht, HashPosition *p
|
||||
uint32_t idx;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
HT_ASSERT(ht->nInternalPointer != &pos || GC_REFCOUNT(ht) == 1);
|
||||
|
||||
for (idx = 0; idx < ht->nNumUsed; idx++) {
|
||||
if (Z_TYPE(ht->arData[idx].val) != IS_UNDEF) {
|
||||
*pos = idx;
|
||||
@ -1534,6 +1756,7 @@ ZEND_API void zend_hash_internal_pointer_end_ex(HashTable *ht, HashPosition *pos
|
||||
uint32_t idx;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
HT_ASSERT(ht->nInternalPointer != &pos || GC_REFCOUNT(ht) == 1);
|
||||
|
||||
idx = ht->nNumUsed;
|
||||
while (idx > 0) {
|
||||
@ -1552,6 +1775,7 @@ ZEND_API int zend_hash_move_forward_ex(HashTable *ht, HashPosition *pos)
|
||||
uint32_t idx = *pos;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
HT_ASSERT(ht->nInternalPointer != &pos || GC_REFCOUNT(ht) == 1);
|
||||
|
||||
if (idx != INVALID_IDX) {
|
||||
while (1) {
|
||||
@ -1575,6 +1799,7 @@ ZEND_API int zend_hash_move_backwards_ex(HashTable *ht, HashPosition *pos)
|
||||
uint32_t idx = *pos;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
HT_ASSERT(ht->nInternalPointer != &pos || GC_REFCOUNT(ht) == 1);
|
||||
|
||||
if (idx != INVALID_IDX) {
|
||||
while (idx > 0) {
|
||||
@ -1708,6 +1933,7 @@ ZEND_API int zend_hash_sort_ex(HashTable *ht, sort_func_t sort, compare_func_t c
|
||||
uint32_t i, j;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
HT_ASSERT(GC_REFCOUNT(ht) == 1);
|
||||
|
||||
if (!(ht->nNumOfElements>1) && !(renumber && ht->nNumOfElements>0)) { /* Doesn't require sorting */
|
||||
return SUCCESS;
|
||||
|
@ -50,8 +50,6 @@ typedef struct _zend_hash_key {
|
||||
|
||||
typedef zend_bool (*merge_checker_func_t)(HashTable *target_ht, zval *source_data, zend_hash_key *hash_key, void *pParam);
|
||||
|
||||
typedef uint32_t HashPosition;
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
|
||||
/* startup/shutdown */
|
||||
@ -171,13 +169,6 @@ ZEND_API zval *zend_hash_get_current_data_ex(HashTable *ht, HashPosition *pos);
|
||||
ZEND_API void zend_hash_internal_pointer_reset_ex(HashTable *ht, HashPosition *pos);
|
||||
ZEND_API void zend_hash_internal_pointer_end_ex(HashTable *ht, HashPosition *pos);
|
||||
|
||||
typedef struct _HashPointer {
|
||||
HashPosition pos;
|
||||
HashTable *ht;
|
||||
zend_ulong h;
|
||||
zend_string *key;
|
||||
} HashPointer;
|
||||
|
||||
#define zend_hash_has_more_elements(ht) \
|
||||
zend_hash_has_more_elements_ex(ht, &(ht)->nInternalPointer)
|
||||
#define zend_hash_move_forward(ht) \
|
||||
@ -222,7 +213,7 @@ ZEND_API zval *zend_hash_minmax(const HashTable *ht, compare_func_t compar, uint
|
||||
|
||||
ZEND_API int zend_hash_rehash(HashTable *ht);
|
||||
|
||||
ZEND_API void zend_array_dup(HashTable *target, HashTable *source);
|
||||
ZEND_API HashTable *zend_array_dup(HashTable *source);
|
||||
ZEND_API void zend_array_destroy(HashTable *ht);
|
||||
ZEND_API void zend_symtable_clean(HashTable *ht);
|
||||
|
||||
@ -234,6 +225,21 @@ void zend_hash_display(const HashTable *ht);
|
||||
|
||||
ZEND_API int _zend_handle_numeric_str_ex(const char *key, size_t length, zend_ulong *idx);
|
||||
|
||||
|
||||
ZEND_API uint32_t zend_hash_iterator_add(HashTable *ht, HashPosition pos);
|
||||
ZEND_API HashPosition zend_hash_iterator_pos(uint32_t idx, HashTable *ht);
|
||||
ZEND_API void zend_hash_iterator_del(uint32_t idx);
|
||||
ZEND_API HashPosition zend_hash_iterators_lower_pos(HashTable *ht, HashPosition start);
|
||||
ZEND_API void _zend_hash_iterators_update(HashTable *ht, HashPosition from, HashPosition to);
|
||||
|
||||
static zend_always_inline void zend_hash_iterators_update(HashTable *ht, HashPosition from, HashPosition to)
|
||||
{
|
||||
if (UNEXPECTED(ht->u.v.nIteratorsCount)) {
|
||||
_zend_hash_iterators_update(ht, from, to);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
END_EXTERN_C()
|
||||
|
||||
#define ZEND_INIT_SYMTABLE(ht) \
|
||||
|
@ -767,15 +767,27 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent
|
||||
zend_string *key;
|
||||
zval *zv;
|
||||
|
||||
if ((ce->ce_flags & ZEND_ACC_INTERFACE)
|
||||
&& !(parent_ce->ce_flags & ZEND_ACC_INTERFACE)) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Interface %s may not inherit from class (%s)", ce->name->val, parent_ce->name->val);
|
||||
}
|
||||
if (parent_ce->ce_flags & ZEND_ACC_FINAL) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Class %s may not inherit from final class (%s)", ce->name->val, parent_ce->name->val);
|
||||
if (ce->ce_flags & ZEND_ACC_INTERFACE) {
|
||||
/* Interface can only inherit other interfaces */
|
||||
if (!(parent_ce->ce_flags & ZEND_ACC_INTERFACE)) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Interface %s may not inherit from class (%s)", ce->name->val, parent_ce->name->val);
|
||||
}
|
||||
} else {
|
||||
/* Class declaration must not extend traits or interfaces */
|
||||
if (parent_ce->ce_flags & ZEND_ACC_INTERFACE) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot extend from interface %s", ce->name->val, parent_ce->name->val);
|
||||
} else if (parent_ce->ce_flags & ZEND_ACC_TRAIT) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot extend from trait %s", ce->name->val, parent_ce->name->val);
|
||||
}
|
||||
|
||||
/* Class must not extend a final class */
|
||||
if (parent_ce->ce_flags & ZEND_ACC_FINAL) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Class %s may not inherit from final class (%s)", ce->name->val, parent_ce->name->val);
|
||||
}
|
||||
}
|
||||
|
||||
ce->parent = parent_ce;
|
||||
|
||||
/* Copy serialize/unserialize callbacks */
|
||||
if (!ce->serialize) {
|
||||
ce->serialize = parent_ce->serialize;
|
||||
@ -1126,7 +1138,7 @@ static void zend_add_trait_method(zend_class_entry *ce, const char *name, zend_s
|
||||
zend_get_function_declaration(existing_fn)->val);
|
||||
}
|
||||
return;
|
||||
} else if ((existing_fn->common.scope->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
|
||||
} else if (existing_fn->common.scope->ce_flags & ZEND_ACC_TRAIT) {
|
||||
/* two traits can't define the same non-abstract method */
|
||||
#if 1
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Trait method %s has not been applied, because there are collisions with other trait methods on %s",
|
||||
|
@ -75,7 +75,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
|
||||
%left '|'
|
||||
%left '^'
|
||||
%left '&'
|
||||
%nonassoc T_IS_EQUAL T_IS_NOT_EQUAL T_IS_IDENTICAL T_IS_NOT_IDENTICAL
|
||||
%nonassoc T_IS_EQUAL T_IS_NOT_EQUAL T_IS_IDENTICAL T_IS_NOT_IDENTICAL T_SPACESHIP
|
||||
%nonassoc '<' T_IS_SMALLER_OR_EQUAL '>' T_IS_GREATER_OR_EQUAL
|
||||
%left T_SL T_SR
|
||||
%left '+' '-' '.'
|
||||
@ -131,6 +131,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
|
||||
%token T_IS_NOT_IDENTICAL "!== (T_IS_NOT_IDENTICAL)"
|
||||
%token T_IS_SMALLER_OR_EQUAL "<= (T_IS_SMALLER_OR_EQUAL)"
|
||||
%token T_IS_GREATER_OR_EQUAL ">= (T_IS_GREATER_OR_EQUAL)"
|
||||
%token T_SPACESHIP "<=> (T_SPACESHIP)"
|
||||
%token T_SL "<< (T_SL)"
|
||||
%token T_SR ">> (T_SR)"
|
||||
%token T_INSTANCEOF "instanceof (T_INSTANCEOF)"
|
||||
@ -846,6 +847,8 @@ expr_without_variable:
|
||||
{ $$ = zend_ast_create(ZEND_AST_GREATER, $1, $3); }
|
||||
| expr T_IS_GREATER_OR_EQUAL expr
|
||||
{ $$ = zend_ast_create(ZEND_AST_GREATER_EQUAL, $1, $3); }
|
||||
| expr T_SPACESHIP expr
|
||||
{ $$ = zend_ast_create_binary_op(ZEND_SPACESHIP, $1, $3); }
|
||||
| expr T_INSTANCEOF class_name_reference
|
||||
{ $$ = zend_ast_create(ZEND_AST_INSTANCEOF, $1, $3); }
|
||||
| '(' expr ')' { $$ = $2; }
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1453,6 +1453,10 @@ NEWLINE ("\r"|"\n"|"\r\n")
|
||||
return T_IS_NOT_EQUAL;
|
||||
}
|
||||
|
||||
<ST_IN_SCRIPTING>"<=>" {
|
||||
return T_SPACESHIP;
|
||||
}
|
||||
|
||||
<ST_IN_SCRIPTING>"<=" {
|
||||
return T_IS_SMALLER_OR_EQUAL;
|
||||
}
|
||||
|
@ -150,9 +150,7 @@ ZEND_API HashTable *zend_std_get_debug_info(zval *object, int *is_temp) /* {{{ *
|
||||
if (Z_TYPE(retval) == IS_ARRAY) {
|
||||
if (Z_IMMUTABLE(retval)) {
|
||||
*is_temp = 1;
|
||||
ALLOC_HASHTABLE(ht);
|
||||
zend_array_dup(ht, Z_ARRVAL(retval));
|
||||
return ht;
|
||||
return zend_array_dup(Z_ARRVAL(retval));
|
||||
} else if (Z_REFCOUNT(retval) <= 1) {
|
||||
*is_temp = 1;
|
||||
ALLOC_HASHTABLE(ht);
|
||||
@ -936,6 +934,7 @@ ZEND_API void zend_std_call_user_call(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */
|
||||
|
||||
/* destruct the function also, then - we have allocated it in get_method */
|
||||
efree_size(func, sizeof(zend_internal_function));
|
||||
execute_data->func = NULL;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -1156,6 +1155,7 @@ ZEND_API void zend_std_callstatic_user_call(INTERNAL_FUNCTION_PARAMETERS) /* {{{
|
||||
|
||||
/* destruct the function also, then - we have allocated it in get_method */
|
||||
efree_size(func, sizeof(zend_internal_function));
|
||||
execute_data->func = NULL;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -766,8 +766,10 @@ ZEND_API int pass_two(zend_op_array *op_array)
|
||||
case ZEND_JMP_SET:
|
||||
case ZEND_COALESCE:
|
||||
case ZEND_NEW:
|
||||
case ZEND_FE_RESET:
|
||||
case ZEND_FE_FETCH:
|
||||
case ZEND_FE_RESET_R:
|
||||
case ZEND_FE_RESET_RW:
|
||||
case ZEND_FE_FETCH_R:
|
||||
case ZEND_FE_FETCH_RW:
|
||||
ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op2);
|
||||
break;
|
||||
case ZEND_VERIFY_RETURN_TYPE:
|
||||
@ -861,6 +863,8 @@ ZEND_API binary_op_type get_binary_op(int opcode)
|
||||
return (binary_op_type) is_smaller_function;
|
||||
case ZEND_IS_SMALLER_OR_EQUAL:
|
||||
return (binary_op_type) is_smaller_or_equal_function;
|
||||
case ZEND_SPACESHIP:
|
||||
return (binary_op_type) compare_function;
|
||||
case ZEND_BW_OR:
|
||||
case ZEND_ASSIGN_BW_OR:
|
||||
return (binary_op_type) bitwise_or_function;
|
||||
|
@ -566,8 +566,7 @@ ZEND_API void convert_to_array(zval *op) /* {{{ */
|
||||
HashTable *obj_ht = Z_OBJ_HT_P(op)->get_properties(op);
|
||||
if (obj_ht) {
|
||||
zval arr;
|
||||
ZVAL_NEW_ARR(&arr);
|
||||
zend_array_dup(Z_ARRVAL(arr), obj_ht);
|
||||
ZVAL_ARR(&arr, zend_array_dup(obj_ht));
|
||||
zval_dtor(op);
|
||||
ZVAL_COPY_VALUE(op, &arr);
|
||||
return;
|
||||
|
@ -106,7 +106,7 @@ static zend_string *zend_new_interned_string_int(zend_string *str)
|
||||
GC_FLAGS(str) |= IS_STR_INTERNED;
|
||||
|
||||
if (CG(interned_strings).nNumUsed >= CG(interned_strings).nTableSize) {
|
||||
if ((CG(interned_strings).nTableSize << 1) > 0) { /* Let's double the table size */
|
||||
if (CG(interned_strings).nTableSize < HT_MAX_SIZE) { /* Let's double the table size */
|
||||
Bucket *d = (Bucket *) perealloc_recoverable(CG(interned_strings).arData, (CG(interned_strings).nTableSize << 1) * sizeof(Bucket), 1);
|
||||
uint32_t *h = (uint32_t *) perealloc_recoverable(CG(interned_strings).arHash, (CG(interned_strings).nTableSize << 1) * sizeof(uint32_t), 1);
|
||||
|
||||
|
@ -209,11 +209,15 @@ static zend_always_inline void zend_string_release(zend_string *s)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static zend_always_inline zend_bool zend_string_equals(zend_string *s1, zend_string *s2)
|
||||
{
|
||||
return s1 == s2 || (s1->len == s2->len && !memcmp(s1->val, s2->val, s1->len));
|
||||
}
|
||||
|
||||
#define zend_string_equals_ci(s1, s2) \
|
||||
((s1)->len == (s2)->len && !zend_binary_strcasecmp((s1)->val, (s1)->len, (s2)->val, (s2)->len))
|
||||
|
||||
#define zend_string_equals_literal_ci(str, c) \
|
||||
((str)->len == sizeof(c) - 1 && !zend_binary_strcasecmp((str)->val, (str)->len, (c), sizeof(c) - 1))
|
||||
|
||||
|
@ -128,6 +128,8 @@ struct _zval_struct {
|
||||
uint32_t cache_slot; /* literal cache slot */
|
||||
uint32_t lineno; /* line number (for ast nodes) */
|
||||
uint32_t num_args; /* arguments number for EX(This) */
|
||||
uint32_t fe_pos; /* foreach position */
|
||||
uint32_t fe_iter_idx; /* foreach iterator index */
|
||||
} u2;
|
||||
};
|
||||
|
||||
@ -157,13 +159,17 @@ typedef struct _Bucket {
|
||||
zend_string *key; /* string key or NULL for numerics */
|
||||
} Bucket;
|
||||
|
||||
typedef struct _HashTable {
|
||||
typedef struct _zend_array HashTable;
|
||||
|
||||
struct _zend_array {
|
||||
zend_refcounted gc;
|
||||
union {
|
||||
struct {
|
||||
ZEND_ENDIAN_LOHI_3(
|
||||
ZEND_ENDIAN_LOHI_4(
|
||||
zend_uchar flags,
|
||||
zend_uchar nApplyCount,
|
||||
uint16_t reserve)
|
||||
zend_uchar nIteratorsCount,
|
||||
zend_uchar reserve)
|
||||
} v;
|
||||
uint32_t flags;
|
||||
} u;
|
||||
@ -176,13 +182,25 @@ typedef struct _HashTable {
|
||||
Bucket *arData;
|
||||
uint32_t *arHash;
|
||||
dtor_func_t pDestructor;
|
||||
} HashTable;
|
||||
|
||||
struct _zend_array {
|
||||
zend_refcounted gc;
|
||||
HashTable ht;
|
||||
};
|
||||
|
||||
#define HT_MIN_SIZE 8
|
||||
|
||||
#if SIZEOF_SIZE_T == 4
|
||||
# define HT_MAX_SIZE 0x04000000 /* small enough to avoid overflow checks */
|
||||
#elif SIZEOF_SIZE_T == 8
|
||||
# define HT_MAX_SIZE 0x80000000
|
||||
#else
|
||||
# error "Unknown SIZEOF_SIZE_T"
|
||||
#endif
|
||||
|
||||
typedef uint32_t HashPosition;
|
||||
|
||||
typedef struct _HashTableIterator {
|
||||
HashTable *ht;
|
||||
HashPosition pos;
|
||||
} HashTableIterator;
|
||||
|
||||
struct _zend_object {
|
||||
zend_refcounted gc;
|
||||
uint32_t handle; // TODO: may be removed ???
|
||||
@ -265,6 +283,12 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
|
||||
#define Z_CACHE_SLOT(zval) (zval).u2.cache_slot
|
||||
#define Z_CACHE_SLOT_P(zval_p) Z_CACHE_SLOT(*(zval_p))
|
||||
|
||||
#define Z_FE_POS(zval) (zval).u2.fe_pos
|
||||
#define Z_FE_POS_P(zval_p) Z_FE_POS(*(zval_p))
|
||||
|
||||
#define Z_FE_ITER(zval) (zval).u2.fe_iter_idx
|
||||
#define Z_FE_ITER_P(zval_p) Z_FE_ITER(*(zval_p))
|
||||
|
||||
#define Z_COUNTED(zval) (zval).value.counted
|
||||
#define Z_COUNTED_P(zval_p) Z_COUNTED(*(zval_p))
|
||||
|
||||
@ -295,6 +319,7 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
|
||||
#define IS_TYPE_REFCOUNTED (1<<2)
|
||||
#define IS_TYPE_COLLECTABLE (1<<3)
|
||||
#define IS_TYPE_COPYABLE (1<<4)
|
||||
#define IS_TYPE_SYMBOLTABLE (1<<5)
|
||||
|
||||
/* extended types */
|
||||
#define IS_INTERNED_STRING_EX IS_STRING
|
||||
@ -367,6 +392,9 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
|
||||
#define Z_IMMUTABLE(zval) ((Z_TYPE_FLAGS(zval) & IS_TYPE_IMMUTABLE) != 0)
|
||||
#define Z_IMMUTABLE_P(zval_p) Z_IMMUTABLE(*(zval_p))
|
||||
|
||||
#define Z_SYMBOLTABLE(zval) ((Z_TYPE_FLAGS(zval) & IS_TYPE_SYMBOLTABLE) != 0)
|
||||
#define Z_SYMBOLTABLE_P(zval_p) Z_SYMBOLTABLE(*(zval_p))
|
||||
|
||||
/* the following Z_OPT_* macros make better code when Z_TYPE_INFO accessed before */
|
||||
#define Z_OPT_TYPE(zval) (Z_TYPE_INFO(zval) & 0xff)
|
||||
#define Z_OPT_TYPE_P(zval_p) Z_OPT_TYPE(*(zval_p))
|
||||
@ -416,7 +444,7 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
|
||||
#define Z_ARR(zval) (zval).value.arr
|
||||
#define Z_ARR_P(zval_p) Z_ARR(*(zval_p))
|
||||
|
||||
#define Z_ARRVAL(zval) (&Z_ARR(zval)->ht)
|
||||
#define Z_ARRVAL(zval) Z_ARR(zval)
|
||||
#define Z_ARRVAL_P(zval_p) Z_ARRVAL(*(zval_p))
|
||||
|
||||
#define Z_OBJ(zval) (zval).value.obj
|
||||
@ -555,8 +583,6 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
|
||||
#define ZVAL_NEW_ARR(z) do { \
|
||||
zval *__z = (z); \
|
||||
zend_array *_arr = emalloc(sizeof(zend_array)); \
|
||||
GC_REFCOUNT(_arr) = 1; \
|
||||
GC_TYPE_INFO(_arr) = IS_ARRAY; \
|
||||
Z_ARR_P(__z) = _arr; \
|
||||
Z_TYPE_INFO_P(__z) = IS_ARRAY_EX; \
|
||||
} while (0)
|
||||
@ -564,8 +590,6 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
|
||||
#define ZVAL_NEW_PERSISTENT_ARR(z) do { \
|
||||
zval *__z = (z); \
|
||||
zend_array *_arr = malloc(sizeof(zend_array)); \
|
||||
GC_REFCOUNT(_arr) = 1; \
|
||||
GC_TYPE_INFO(_arr) = IS_ARRAY; \
|
||||
Z_ARR_P(__z) = _arr; \
|
||||
Z_TYPE_INFO_P(__z) = IS_ARRAY_EX; \
|
||||
} while (0)
|
||||
@ -688,7 +712,7 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
|
||||
#define Z_TRY_DELREF(z) Z_TRY_DELREF_P(&(z))
|
||||
|
||||
static zend_always_inline uint32_t zval_refcount_p(zval* pz) {
|
||||
ZEND_ASSERT(Z_REFCOUNTED_P(pz) || Z_IMMUTABLE_P(pz));
|
||||
ZEND_ASSERT(Z_REFCOUNTED_P(pz) || Z_IMMUTABLE_P(pz) || Z_SYMBOLTABLE_P(pz));
|
||||
return GC_REFCOUNT(Z_COUNTED_P(pz));
|
||||
}
|
||||
|
||||
|
@ -40,15 +40,13 @@ ZEND_API void _zval_dtor_func(zend_refcounted *p ZEND_FILE_LINE_DC)
|
||||
case IS_ARRAY: {
|
||||
zend_array *arr = (zend_array*)p;
|
||||
|
||||
if (arr != &EG(symbol_table)) {
|
||||
ZEND_ASSERT(GC_REFCOUNT(arr) <= 1);
|
||||
ZEND_ASSERT(GC_REFCOUNT(arr) <= 1);
|
||||
|
||||
/* break possible cycles */
|
||||
GC_TYPE(arr) = IS_NULL;
|
||||
GC_REMOVE_FROM_BUFFER(arr);
|
||||
zend_array_destroy(&arr->ht);
|
||||
efree_size(arr, sizeof(zend_array));
|
||||
}
|
||||
/* break possible cycles */
|
||||
GC_TYPE(arr) = IS_NULL;
|
||||
GC_REMOVE_FROM_BUFFER(arr);
|
||||
zend_array_destroy(arr);
|
||||
efree_size(arr, sizeof(zend_array));
|
||||
break;
|
||||
}
|
||||
case IS_CONSTANT_AST: {
|
||||
@ -100,13 +98,11 @@ ZEND_API void _zval_dtor_func_for_ptr(zend_refcounted *p ZEND_FILE_LINE_DC)
|
||||
case IS_ARRAY: {
|
||||
zend_array *arr = (zend_array*)p;
|
||||
|
||||
if (arr != &EG(symbol_table)) {
|
||||
/* break possible cycles */
|
||||
GC_TYPE(arr) = IS_NULL;
|
||||
GC_REMOVE_FROM_BUFFER(arr);
|
||||
zend_array_destroy(&arr->ht);
|
||||
efree_size(arr, sizeof(zend_array));
|
||||
}
|
||||
/* break possible cycles */
|
||||
GC_TYPE(arr) = IS_NULL;
|
||||
GC_REMOVE_FROM_BUFFER(arr);
|
||||
zend_array_destroy(arr);
|
||||
efree_size(arr, sizeof(zend_array));
|
||||
break;
|
||||
}
|
||||
case IS_CONSTANT_AST: {
|
||||
@ -237,16 +233,8 @@ ZEND_API void _zval_copy_ctor_func(zval *zvalue ZEND_FILE_LINE_DC)
|
||||
CHECK_ZVAL_STRING_REL(Z_STR_P(zvalue));
|
||||
Z_STR_P(zvalue) = zend_string_dup(Z_STR_P(zvalue), 0);
|
||||
break;
|
||||
case IS_ARRAY: {
|
||||
HashTable *ht;
|
||||
|
||||
if (Z_ARR_P(zvalue) == &EG(symbol_table)) {
|
||||
return; /* do nothing */
|
||||
}
|
||||
ht = Z_ARRVAL_P(zvalue);
|
||||
ZVAL_NEW_ARR(zvalue);
|
||||
zend_array_dup(Z_ARRVAL_P(zvalue), ht);
|
||||
}
|
||||
case IS_ARRAY:
|
||||
ZVAL_ARR(zvalue, zend_array_dup(Z_ARRVAL_P(zvalue)));
|
||||
break;
|
||||
case IS_CONSTANT_AST: {
|
||||
zend_ast_ref *ast = emalloc(sizeof(zend_ast_ref));
|
||||
@ -315,13 +303,13 @@ ZEND_API int zval_copy_static_var(zval *p, int num_args, va_list args, zend_hash
|
||||
is_ref = Z_CONST_FLAGS_P(p) & IS_LEXICAL_REF;
|
||||
|
||||
symbol_table = zend_rebuild_symbol_table();
|
||||
p = zend_hash_find(&symbol_table->ht, key->key);
|
||||
p = zend_hash_find(symbol_table, key->key);
|
||||
if (!p) {
|
||||
p = &tmp;
|
||||
ZVAL_NULL(&tmp);
|
||||
if (is_ref) {
|
||||
ZVAL_NEW_REF(&tmp, &tmp);
|
||||
zend_hash_add_new(&symbol_table->ht, key->key, &tmp);
|
||||
zend_hash_add_new(symbol_table, key->key, &tmp);
|
||||
Z_ADDREF_P(p);
|
||||
} else {
|
||||
zend_error(E_NOTICE,"Undefined variable: %s", key->key->val);
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -21,7 +21,7 @@
|
||||
#include <stdio.h>
|
||||
#include <zend.h>
|
||||
|
||||
const char *zend_vm_opcodes_map[170] = {
|
||||
const char *zend_vm_opcodes_map[171] = {
|
||||
"ZEND_NOP",
|
||||
"ZEND_ADD",
|
||||
"ZEND_SUB",
|
||||
@ -99,8 +99,8 @@ const char *zend_vm_opcodes_map[170] = {
|
||||
"ZEND_UNSET_VAR",
|
||||
"ZEND_UNSET_DIM",
|
||||
"ZEND_UNSET_OBJ",
|
||||
"ZEND_FE_RESET",
|
||||
"ZEND_FE_FETCH",
|
||||
"ZEND_FE_RESET_R",
|
||||
"ZEND_FE_FETCH_R",
|
||||
"ZEND_EXIT",
|
||||
"ZEND_FETCH_R",
|
||||
"ZEND_FETCH_DIM_R",
|
||||
@ -147,9 +147,9 @@ const char *zend_vm_opcodes_map[170] = {
|
||||
"ZEND_DEFINED",
|
||||
"ZEND_TYPE_CHECK",
|
||||
"ZEND_VERIFY_RETURN_TYPE",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
"ZEND_FE_RESET_RW",
|
||||
"ZEND_FE_FETCH_RW",
|
||||
"ZEND_FE_FREE",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
@ -192,6 +192,7 @@ const char *zend_vm_opcodes_map[170] = {
|
||||
"ZEND_ASSIGN_POW",
|
||||
"ZEND_BIND_GLOBAL",
|
||||
"ZEND_COALESCE",
|
||||
"ZEND_SPACESHIP",
|
||||
};
|
||||
|
||||
ZEND_API const char* zend_get_opcode_name(zend_uchar opcode) {
|
||||
|
@ -101,8 +101,8 @@ END_EXTERN_C()
|
||||
#define ZEND_UNSET_VAR 74
|
||||
#define ZEND_UNSET_DIM 75
|
||||
#define ZEND_UNSET_OBJ 76
|
||||
#define ZEND_FE_RESET 77
|
||||
#define ZEND_FE_FETCH 78
|
||||
#define ZEND_FE_RESET_R 77
|
||||
#define ZEND_FE_FETCH_R 78
|
||||
#define ZEND_EXIT 79
|
||||
#define ZEND_FETCH_R 80
|
||||
#define ZEND_FETCH_DIM_R 81
|
||||
@ -149,6 +149,9 @@ END_EXTERN_C()
|
||||
#define ZEND_DEFINED 122
|
||||
#define ZEND_TYPE_CHECK 123
|
||||
#define ZEND_VERIFY_RETURN_TYPE 124
|
||||
#define ZEND_FE_RESET_RW 125
|
||||
#define ZEND_FE_FETCH_RW 126
|
||||
#define ZEND_FE_FREE 127
|
||||
#define ZEND_PRE_INC_OBJ 132
|
||||
#define ZEND_PRE_DEC_OBJ 133
|
||||
#define ZEND_POST_INC_OBJ 134
|
||||
@ -182,5 +185,6 @@ END_EXTERN_C()
|
||||
#define ZEND_ASSIGN_POW 167
|
||||
#define ZEND_BIND_GLOBAL 168
|
||||
#define ZEND_COALESCE 169
|
||||
#define ZEND_SPACESHIP 170
|
||||
|
||||
#endif
|
||||
|
@ -128,7 +128,7 @@ zend_module_entry bcmath_module_entry = {
|
||||
|
||||
#ifdef COMPILE_DL_BCMATH
|
||||
#ifdef ZTS
|
||||
ZEND_TSRMLS_CACHE_DEFINE;
|
||||
ZEND_TSRMLS_CACHE_DEFINE();
|
||||
#endif
|
||||
ZEND_GET_MODULE(bcmath)
|
||||
#endif
|
||||
@ -144,7 +144,7 @@ PHP_INI_END()
|
||||
static PHP_GINIT_FUNCTION(bcmath)
|
||||
{
|
||||
#if defined(COMPILE_DL_BCMATH) && defined(ZTS)
|
||||
ZEND_TSRMLS_CACHE_UPDATE;
|
||||
ZEND_TSRMLS_CACHE_UPDATE();
|
||||
#endif
|
||||
bcmath_globals->bc_precision = 0;
|
||||
bc_init_numbers();
|
||||
|
@ -51,7 +51,7 @@ ZEND_END_MODULE_GLOBALS(bcmath)
|
||||
#ifdef ZTS
|
||||
# define BCG(v) ZEND_TSRMG(bcmath_globals_id, zend_bcmath_globals *, v)
|
||||
# ifdef COMPILE_DL_BCMATH
|
||||
ZEND_TSRMLS_CACHE_EXTERN;
|
||||
ZEND_TSRMLS_CACHE_EXTERN();
|
||||
# endif
|
||||
#else
|
||||
# define BCG(v) (bcmath_globals.v)
|
||||
|
@ -255,7 +255,7 @@ zend_module_entry com_dotnet_module_entry = {
|
||||
|
||||
#ifdef COMPILE_DL_COM_DOTNET
|
||||
#ifdef ZTS
|
||||
ZEND_TSRMLS_CACHE_DEFINE;
|
||||
ZEND_TSRMLS_CACHE_DEFINE();
|
||||
#endif
|
||||
ZEND_GET_MODULE(com_dotnet)
|
||||
#endif
|
||||
@ -341,7 +341,7 @@ PHP_INI_END()
|
||||
static PHP_GINIT_FUNCTION(com_dotnet)
|
||||
{
|
||||
#if defined(COMPILE_DL_COM_DOTNET) && defined(ZTS)
|
||||
ZEND_TSRMLS_CACHE_UPDATE;
|
||||
ZEND_TSRMLS_CACHE_UPDATE();
|
||||
#endif
|
||||
memset(com_dotnet_globals, 0, sizeof(*com_dotnet_globals));
|
||||
com_dotnet_globals->code_page = CP_ACP;
|
||||
|
@ -55,7 +55,7 @@ ZEND_END_MODULE_GLOBALS(com_dotnet)
|
||||
#ifdef ZTS
|
||||
# define COMG(v) ZEND_TSRMG(com_dotnet_globals_id, zend_com_dotnet_globals *, v)
|
||||
# ifdef COMPILE_DL_COM_DOTNET
|
||||
ZEND_TSRMLS_CACHE_EXTERN;
|
||||
ZEND_TSRMLS_CACHE_EXTERN();
|
||||
# endif
|
||||
#else
|
||||
# define COMG(v) (com_dotnet_globals.v)
|
||||
|
@ -2004,12 +2004,13 @@ PHP_FUNCTION(curl_copy_handle)
|
||||
static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{ */
|
||||
{
|
||||
CURLcode error = CURLE_OK;
|
||||
zend_long lval;
|
||||
|
||||
switch (option) {
|
||||
/* Long options */
|
||||
case CURLOPT_SSL_VERIFYHOST:
|
||||
convert_to_long(zvalue);
|
||||
if (Z_LVAL_P(zvalue) == 1) {
|
||||
lval = zval_get_long(zvalue);
|
||||
if (lval == 1) {
|
||||
#if LIBCURL_VERSION_NUM <= 0x071c00 /* 7.28.0 */
|
||||
php_error_docref(NULL, E_NOTICE, "CURLOPT_SSL_VERIFYHOST with value 1 is deprecated and will be removed as of libcurl 7.28.1. It is recommended to use value 2 instead");
|
||||
#else
|
||||
@ -2163,19 +2164,19 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{
|
||||
#if CURLOPT_MUTE != 0
|
||||
case CURLOPT_MUTE:
|
||||
#endif
|
||||
convert_to_long_ex(zvalue);
|
||||
lval = zval_get_long(zvalue);
|
||||
#if LIBCURL_VERSION_NUM >= 0x71304
|
||||
if ((option == CURLOPT_PROTOCOLS || option == CURLOPT_REDIR_PROTOCOLS) &&
|
||||
(PG(open_basedir) && *PG(open_basedir)) && (Z_LVAL_P(zvalue) & CURLPROTO_FILE)) {
|
||||
(PG(open_basedir) && *PG(open_basedir)) && (lval & CURLPROTO_FILE)) {
|
||||
php_error_docref(NULL, E_WARNING, "CURLPROTO_FILE cannot be activated when an open_basedir is set");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
error = curl_easy_setopt(ch->cp, option, Z_LVAL_P(zvalue));
|
||||
error = curl_easy_setopt(ch->cp, option, lval);
|
||||
break;
|
||||
case CURLOPT_SAFE_UPLOAD:
|
||||
convert_to_long_ex(zvalue);
|
||||
ch->safe_upload = (Z_LVAL_P(zvalue) != 0);
|
||||
lval = zval_get_long(zvalue);
|
||||
ch->safe_upload = (lval != 0);
|
||||
break;
|
||||
|
||||
/* String options */
|
||||
@ -2236,8 +2237,10 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{
|
||||
case CURLOPT_MAIL_AUTH:
|
||||
#endif
|
||||
{
|
||||
convert_to_string_ex(zvalue);
|
||||
return php_curl_option_str(ch, option, Z_STRVAL_P(zvalue), Z_STRLEN_P(zvalue), 0);
|
||||
zend_string *str = zval_get_string(zvalue);
|
||||
int ret = php_curl_option_str(ch, option, str->val, str->len, 0);
|
||||
zend_string_release(str);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Curl nullable string options */
|
||||
@ -2259,21 +2262,31 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{
|
||||
if (Z_ISNULL_P(zvalue)) {
|
||||
error = curl_easy_setopt(ch->cp, option, NULL);
|
||||
} else {
|
||||
convert_to_string_ex(zvalue);
|
||||
return php_curl_option_str(ch, option, Z_STRVAL_P(zvalue), Z_STRLEN_P(zvalue), 0);
|
||||
zend_string *str = zval_get_string(zvalue);
|
||||
int ret = php_curl_option_str(ch, option, str->val, str->len, 0);
|
||||
zend_string_release(str);
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Curl private option */
|
||||
case CURLOPT_PRIVATE:
|
||||
convert_to_string_ex(zvalue);
|
||||
return php_curl_option_str(ch, option, Z_STRVAL_P(zvalue), Z_STRLEN_P(zvalue), 1);
|
||||
{
|
||||
zend_string *str = zval_get_string(zvalue);
|
||||
int ret = php_curl_option_str(ch, option, str->val, str->len, 1);
|
||||
zend_string_release(str);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Curl url option */
|
||||
case CURLOPT_URL:
|
||||
convert_to_string_ex(zvalue);
|
||||
return php_curl_option_url(ch, Z_STRVAL_P(zvalue), Z_STRLEN_P(zvalue));
|
||||
{
|
||||
zend_string *str = zval_get_string(zvalue);
|
||||
int ret = php_curl_option_url(ch, str->val, str->len);
|
||||
zend_string_release(str);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Curl file handle options */
|
||||
case CURLOPT_FILE:
|
||||
@ -2450,16 +2463,16 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{
|
||||
break;
|
||||
|
||||
case CURLOPT_FOLLOWLOCATION:
|
||||
convert_to_long_ex(zvalue);
|
||||
lval = zval_get_long(zvalue);
|
||||
#if LIBCURL_VERSION_NUM < 0x071304
|
||||
if (PG(open_basedir) && *PG(open_basedir)) {
|
||||
if (Z_LVAL_P(zvalue) != 0) {
|
||||
if (lval != 0) {
|
||||
php_error_docref(NULL, E_WARNING, "CURLOPT_FOLLOWLOCATION cannot be activated when an open_basedir is set");
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
error = curl_easy_setopt(ch->cp, option, Z_LVAL_P(zvalue));
|
||||
error = curl_easy_setopt(ch->cp, option, lval);
|
||||
break;
|
||||
|
||||
case CURLOPT_HEADERFUNCTION:
|
||||
@ -2593,19 +2606,21 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{
|
||||
error = curl_easy_setopt(ch->cp, CURLOPT_HTTPPOST, first);
|
||||
} else {
|
||||
#if LIBCURL_VERSION_NUM >= 0x071101
|
||||
convert_to_string_ex(zvalue);
|
||||
zend_string *str = zval_get_string(zvalue);
|
||||
/* with curl 7.17.0 and later, we can use COPYPOSTFIELDS, but we have to provide size before */
|
||||
error = curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDSIZE, Z_STRLEN_P(zvalue));
|
||||
error = curl_easy_setopt(ch->cp, CURLOPT_COPYPOSTFIELDS, Z_STRVAL_P(zvalue));
|
||||
error = curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDSIZE, str->len);
|
||||
error = curl_easy_setopt(ch->cp, CURLOPT_COPYPOSTFIELDS, str->val);
|
||||
zend_string_release(str);
|
||||
#else
|
||||
char *post = NULL;
|
||||
zend_string *str = zval_get_string(zvalue);
|
||||
|
||||
convert_to_string_ex(zvalue);
|
||||
post = estrndup(Z_STRVAL_P(zvalue), Z_STRLEN_P(zvalue));
|
||||
post = estrndup(str->val, str->len);
|
||||
zend_llist_add_element(&ch->to_free->str, &post);
|
||||
|
||||
curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDS, post);
|
||||
error = curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDSIZE, Z_STRLEN_P(zvalue));
|
||||
error = curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDSIZE, str->len);
|
||||
zend_string_release(str);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
@ -2633,8 +2648,8 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{
|
||||
break;
|
||||
|
||||
case CURLOPT_RETURNTRANSFER:
|
||||
convert_to_long_ex(zvalue);
|
||||
if (Z_LVAL_P(zvalue)) {
|
||||
lval = zval_get_long(zvalue);
|
||||
if (lval) {
|
||||
ch->handlers->write->method = PHP_CURL_RETURN;
|
||||
} else {
|
||||
ch->handlers->write->method = PHP_CURL_STDOUT;
|
||||
@ -2653,15 +2668,15 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{
|
||||
#if LIBCURL_VERSION_NUM >= 0x070f05 /* Available since 7.15.5 */
|
||||
case CURLOPT_MAX_RECV_SPEED_LARGE:
|
||||
case CURLOPT_MAX_SEND_SPEED_LARGE:
|
||||
convert_to_long_ex(zvalue);
|
||||
error = curl_easy_setopt(ch->cp, option, (curl_off_t)Z_LVAL_P(zvalue));
|
||||
lval = zval_get_long(zvalue);
|
||||
error = curl_easy_setopt(ch->cp, option, (curl_off_t)lval);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LIBCURL_VERSION_NUM >= 0x071301 /* Available since 7.19.1 */
|
||||
case CURLOPT_POSTREDIR:
|
||||
convert_to_long_ex(zvalue);
|
||||
error = curl_easy_setopt(ch->cp, CURLOPT_POSTREDIR, Z_LVAL_P(zvalue) & CURL_REDIR_POST_ALL);
|
||||
lval = zval_get_long(zvalue);
|
||||
error = curl_easy_setopt(ch->cp, CURLOPT_POSTREDIR, lval & CURL_REDIR_POST_ALL);
|
||||
break;
|
||||
#endif
|
||||
|
||||
@ -2696,18 +2711,22 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{
|
||||
case CURLOPT_SSH_KNOWNHOSTS:
|
||||
#endif
|
||||
{
|
||||
convert_to_string_ex(zvalue);
|
||||
zend_string *str = zval_get_string(zvalue);
|
||||
int ret;
|
||||
|
||||
if (Z_STRLEN_P(zvalue) && php_check_open_basedir(Z_STRVAL_P(zvalue))) {
|
||||
if (str->len && php_check_open_basedir(str->val)) {
|
||||
zend_string_release(str);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return php_curl_option_str(ch, option, Z_STRVAL_P(zvalue), Z_STRLEN_P(zvalue), 0);
|
||||
ret = php_curl_option_str(ch, option, str->val, str->len, 0);
|
||||
zend_string_release(str);
|
||||
return ret;
|
||||
}
|
||||
|
||||
case CURLINFO_HEADER_OUT:
|
||||
convert_to_long_ex(zvalue);
|
||||
if (Z_LVAL_P(zvalue) == 1) {
|
||||
lval = zval_get_long(zvalue);
|
||||
if (lval == 1) {
|
||||
curl_easy_setopt(ch->cp, CURLOPT_DEBUGFUNCTION, curl_debug);
|
||||
curl_easy_setopt(ch->cp, CURLOPT_DEBUGDATA, (void *)ch);
|
||||
curl_easy_setopt(ch->cp, CURLOPT_VERBOSE, 1);
|
||||
|
@ -2720,15 +2720,11 @@ static int php_date_initialize_from_hash(php_date_obj **dateobj, HashTable *myht
|
||||
php_timezone_obj *tzobj;
|
||||
|
||||
z_date = zend_hash_str_find(myht, "date", sizeof("data")-1);
|
||||
if (z_date) {
|
||||
convert_to_string(z_date);
|
||||
if (z_date && Z_TYPE_P(z_date) == IS_STRING) {
|
||||
z_timezone_type = zend_hash_str_find(myht, "timezone_type", sizeof("timezone_type")-1);
|
||||
if (z_timezone_type) {
|
||||
convert_to_long(z_timezone_type);
|
||||
if (z_timezone_type && Z_TYPE_P(z_timezone_type) == IS_LONG) {
|
||||
z_timezone = zend_hash_str_find(myht, "timezone", sizeof("timezone")-1);
|
||||
if (z_timezone) {
|
||||
convert_to_string(z_timezone);
|
||||
|
||||
if (z_timezone && Z_TYPE_P(z_timezone) == IS_STRING) {
|
||||
switch (Z_LVAL_P(z_timezone_type)) {
|
||||
case TIMELIB_ZONETYPE_OFFSET:
|
||||
case TIMELIB_ZONETYPE_ABBR: {
|
||||
@ -2742,7 +2738,6 @@ static int php_date_initialize_from_hash(php_date_obj **dateobj, HashTable *myht
|
||||
|
||||
case TIMELIB_ZONETYPE_ID: {
|
||||
int ret;
|
||||
convert_to_string(z_timezone);
|
||||
|
||||
tzi = php_date_parse_tzfile(Z_STRVAL_P(z_timezone), DATE_TIMEZONEDB);
|
||||
|
||||
@ -3657,7 +3652,9 @@ static int php_date_timezone_initialize_from_hash(zval **return_value, php_timez
|
||||
|
||||
if ((z_timezone_type = zend_hash_str_find(myht, "timezone_type", sizeof("timezone_type")-1)) != NULL) {
|
||||
if ((z_timezone = zend_hash_str_find(myht, "timezone", sizeof("timezone")-1)) != NULL) {
|
||||
convert_to_long(z_timezone_type);
|
||||
if(Z_TYPE_P(z_timezone_type) != IS_LONG) {
|
||||
return FAILURE;
|
||||
}
|
||||
if (SUCCESS == timezone_initialize(*tzobj, Z_STRVAL_P(z_timezone))) {
|
||||
return SUCCESS;
|
||||
}
|
||||
@ -3682,7 +3679,9 @@ PHP_METHOD(DateTimeZone, __set_state)
|
||||
|
||||
php_date_instantiate(date_ce_timezone, return_value);
|
||||
tzobj = Z_PHPTIMEZONE_P(return_value);
|
||||
php_date_timezone_initialize_from_hash(&return_value, &tzobj, myht);
|
||||
if(php_date_timezone_initialize_from_hash(&return_value, &tzobj, myht) != SUCCESS) {
|
||||
php_error_docref(NULL, E_ERROR, "Timezone initialization failed");
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -3698,7 +3697,9 @@ PHP_METHOD(DateTimeZone, __wakeup)
|
||||
|
||||
myht = Z_OBJPROP_P(object);
|
||||
|
||||
php_date_timezone_initialize_from_hash(&return_value, &tzobj, myht);
|
||||
if(php_date_timezone_initialize_from_hash(&return_value, &tzobj, myht) != SUCCESS) {
|
||||
php_error_docref(NULL, E_ERROR, "Timezone initialization failed");
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
9
ext/date/tests/bug68942.phpt
Normal file
9
ext/date/tests/bug68942.phpt
Normal file
@ -0,0 +1,9 @@
|
||||
--TEST--
|
||||
Bug #68942 (Use after free vulnerability in unserialize() with DateTimeZone).
|
||||
--FILE--
|
||||
<?php
|
||||
$data = unserialize('a:2:{i:0;O:12:"DateTimeZone":2:{s:13:"timezone_type";a:2:{i:0;i:1;i:1;i:2;}s:8:"timezone";s:1:"A";}i:1;R:4;}');
|
||||
var_dump($data);
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: DateTimeZone::__wakeup(): Timezone initialization failed in %s/bug68942.php on line %d
|
9
ext/date/tests/bug68942_2.phpt
Normal file
9
ext/date/tests/bug68942_2.phpt
Normal file
@ -0,0 +1,9 @@
|
||||
--TEST--
|
||||
Bug #68942 (Use after free vulnerability in unserialize() with DateTime).
|
||||
--FILE--
|
||||
<?php
|
||||
$data = unserialize('a:2:{i:0;O:8:"DateTime":3:{s:4:"date";s:26:"2000-01-01 00:00:00.000000";s:13:"timezone_type";a:2:{i:0;i:1;i:1;i:2;}s:8:"timezone";s:1:"A";}i:1;R:5;}');
|
||||
var_dump($data);
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Invalid serialization data for DateTime object in %s/bug68942_2.php on line %d
|
@ -418,16 +418,14 @@ static HashTable* dom_get_debug_info_helper(zval *object, int *is_temp) /* {{{ *
|
||||
HashTable *debug_info,
|
||||
*prop_handlers = obj->prop_handler,
|
||||
*std_props;
|
||||
HashPosition pos;
|
||||
zend_string *string_key;
|
||||
dom_prop_handler *entry;
|
||||
zval object_value;
|
||||
|
||||
*is_temp = 1;
|
||||
|
||||
ALLOC_HASHTABLE(debug_info);
|
||||
|
||||
std_props = zend_std_get_properties(object);
|
||||
zend_array_dup(debug_info, std_props);
|
||||
debug_info = zend_array_dup(std_props);
|
||||
|
||||
if (!prop_handlers) {
|
||||
return debug_info;
|
||||
@ -435,19 +433,10 @@ static HashTable* dom_get_debug_info_helper(zval *object, int *is_temp) /* {{{ *
|
||||
|
||||
ZVAL_STRING(&object_value, "(object value omitted)");
|
||||
|
||||
for (zend_hash_internal_pointer_reset_ex(prop_handlers, &pos);
|
||||
(entry = zend_hash_get_current_data_ptr_ex(prop_handlers, &pos)) != NULL;
|
||||
zend_hash_move_forward_ex(prop_handlers, &pos)) {
|
||||
ZEND_HASH_FOREACH_STR_KEY_PTR(prop_handlers, string_key, entry) {
|
||||
zval value;
|
||||
zend_string *string_key;
|
||||
zend_ulong num_key;
|
||||
|
||||
if (entry->read_func(obj, &value) == FAILURE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (zend_hash_get_current_key_ex(prop_handlers, &string_key,
|
||||
&num_key, &pos) != HASH_KEY_IS_STRING) {
|
||||
if (entry->read_func(obj, &value) == FAILURE || !string_key) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -457,7 +446,7 @@ static HashTable* dom_get_debug_info_helper(zval *object, int *is_temp) /* {{{ *
|
||||
}
|
||||
|
||||
zend_hash_add(debug_info, string_key, &value);
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
zval_dtor(&object_value);
|
||||
|
||||
|
@ -520,14 +520,12 @@ PHP_FUNCTION(dom_xpath_register_php_functions)
|
||||
|
||||
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "a", &array_value) == SUCCESS) {
|
||||
intern = Z_XPATHOBJ_P(id);
|
||||
zend_hash_internal_pointer_reset(Z_ARRVAL_P(array_value));
|
||||
while ((entry = zend_hash_get_current_data(Z_ARRVAL_P(array_value)))) {
|
||||
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(array_value), entry) {
|
||||
zend_string *str = zval_get_string(entry);
|
||||
ZVAL_LONG(&new_string,1);
|
||||
zend_hash_update(intern->registered_phpfunctions, str, &new_string);
|
||||
zend_hash_move_forward(Z_ARRVAL_P(array_value));
|
||||
zend_string_release(str);
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
intern->registerPhpFunctions = 2;
|
||||
RETURN_TRUE;
|
||||
|
||||
|
@ -552,13 +552,12 @@ PHP_FUNCTION(enchant_broker_request_dict)
|
||||
|
||||
d = enchant_broker_request_dict(pbroker->pbroker, (const char *)tag);
|
||||
if (d) {
|
||||
pos = pbroker->dictcnt++;
|
||||
if (pbroker->dictcnt) {
|
||||
pbroker->dict = (enchant_dict **)erealloc(pbroker->dict, sizeof(enchant_dict *) * pbroker->dictcnt);
|
||||
pos = pbroker->dictcnt++;
|
||||
} else {
|
||||
pbroker->dict = (enchant_dict **)emalloc(sizeof(enchant_dict *));
|
||||
pos = 0;
|
||||
pbroker->dictcnt++;
|
||||
}
|
||||
|
||||
dict = pbroker->dict[pos] = (enchant_dict *)emalloc(sizeof(enchant_dict));
|
||||
@ -604,14 +603,14 @@ PHP_FUNCTION(enchant_broker_request_pwl_dict)
|
||||
|
||||
d = enchant_broker_request_pwl_dict(pbroker->pbroker, (const char *)pwl);
|
||||
if (d) {
|
||||
pos = pbroker->dictcnt++;
|
||||
if (pbroker->dictcnt) {
|
||||
pos = pbroker->dictcnt++;
|
||||
pbroker->dict = (enchant_dict **)erealloc(pbroker->dict, sizeof(enchant_dict *) * pbroker->dictcnt);
|
||||
} else {
|
||||
pbroker->dict = (enchant_dict **)emalloc(sizeof(enchant_dict *));
|
||||
pos = 0;
|
||||
pbroker->dictcnt++;
|
||||
}
|
||||
|
||||
dict = pbroker->dict[pos] = (enchant_dict *)emalloc(sizeof(enchant_dict));
|
||||
dict->id = pos;
|
||||
dict->pbroker = pbroker;
|
||||
|
@ -158,7 +158,7 @@ ZEND_DECLARE_MODULE_GLOBALS(exif)
|
||||
#ifdef ZTS
|
||||
#define EXIF_G(v) ZEND_TSRMG(exif_globals_id, zend_exif_globals *, v)
|
||||
#ifdef COMPILE_DL_EXIF
|
||||
ZEND_TSRMLS_CACHE_DEFINE;
|
||||
ZEND_TSRMLS_CACHE_DEFINE();
|
||||
#endif
|
||||
#else
|
||||
#define EXIF_G(v) (exif_globals.v)
|
||||
@ -212,7 +212,7 @@ PHP_INI_END()
|
||||
static PHP_GINIT_FUNCTION(exif)
|
||||
{
|
||||
#if defined(COMPILE_DL_EXIF) && defined(ZTS)
|
||||
ZEND_TSRMLS_CACHE_UPDATE;
|
||||
ZEND_TSRMLS_CACHE_UPDATE();
|
||||
#endif
|
||||
exif_globals->encode_unicode = NULL;
|
||||
exif_globals->decode_unicode_be = NULL;
|
||||
|
@ -2192,7 +2192,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
|
||||
+ zval_ptr_dtor(&patt);
|
||||
+
|
||||
+ ZVAL_STRING(&repl, rep);
|
||||
+ res = php_pcre_replace_impl(pce, ms->o.buf, strlen(ms->o.buf), &repl, 0, -1, &rep_cnt);
|
||||
+ res = php_pcre_replace_impl(pce, NULL, ms->o.buf, strlen(ms->o.buf), &repl, 0, -1, &rep_cnt);
|
||||
+
|
||||
+ zval_ptr_dtor(&repl);
|
||||
+ if (NULL == res) {
|
||||
|
@ -457,7 +457,7 @@ file_replace(struct magic_set *ms, const char *pat, const char *rep)
|
||||
zval_ptr_dtor(&patt);
|
||||
|
||||
ZVAL_STRING(&repl, rep);
|
||||
res = php_pcre_replace_impl(pce, ms->o.buf, strlen(ms->o.buf), &repl, 0, -1, &rep_cnt);
|
||||
res = php_pcre_replace_impl(pce, NULL, ms->o.buf, strlen(ms->o.buf), &repl, 0, -1, &rep_cnt);
|
||||
|
||||
zval_ptr_dtor(&repl);
|
||||
if (NULL == res) {
|
||||
|
@ -154,7 +154,7 @@ zend_module_entry filter_module_entry = {
|
||||
|
||||
#ifdef COMPILE_DL_FILTER
|
||||
#ifdef ZTS
|
||||
ZEND_TSRMLS_CACHE_DEFINE;
|
||||
ZEND_TSRMLS_CACHE_DEFINE();
|
||||
#endif
|
||||
ZEND_GET_MODULE(filter)
|
||||
#endif
|
||||
@ -196,7 +196,7 @@ PHP_INI_END()
|
||||
static void php_filter_init_globals(zend_filter_globals *filter_globals) /* {{{ */
|
||||
{
|
||||
#if defined(COMPILE_DL_FILTER) && defined(ZTS)
|
||||
ZEND_TSRMLS_CACHE_UPDATE;
|
||||
ZEND_TSRMLS_CACHE_UPDATE();
|
||||
#endif
|
||||
ZVAL_UNDEF(&filter_globals->post_array);
|
||||
ZVAL_UNDEF(&filter_globals->get_array);
|
||||
@ -534,17 +534,13 @@ static zval *php_filter_get_storage(zend_long arg)/* {{{ */
|
||||
break;
|
||||
case PARSE_SERVER:
|
||||
if (PG(auto_globals_jit)) {
|
||||
zend_string *name = zend_string_init("_SERVER", sizeof("_SERVER") - 1, 0);
|
||||
zend_is_auto_global(name);
|
||||
zend_string_release(name);
|
||||
zend_is_auto_global_str(ZEND_STRL("_SERVER"));
|
||||
}
|
||||
array_ptr = &IF_G(server_array);
|
||||
break;
|
||||
case PARSE_ENV:
|
||||
if (PG(auto_globals_jit)) {
|
||||
zend_string *name = zend_string_init("_ENV", sizeof("_ENV") - 1, 0);
|
||||
zend_is_auto_global(name);
|
||||
zend_string_release(name);
|
||||
zend_is_auto_global_str(ZEND_STRL("_ENV"));
|
||||
}
|
||||
array_ptr = &IF_G(env_array) ? &IF_G(env_array) : &PG(http_globals)[TRACK_VARS_ENV];
|
||||
break;
|
||||
|
@ -65,7 +65,7 @@ ZEND_END_MODULE_GLOBALS(filter)
|
||||
|
||||
#ifdef ZTS
|
||||
#define IF_G(v) ZEND_TSRMG(filter_globals_id, zend_filter_globals *, v)
|
||||
ZEND_TSRMLS_CACHE_EXTERN;
|
||||
ZEND_TSRMLS_CACHE_EXTERN();
|
||||
#else
|
||||
#define IF_G(v) (filter_globals.v)
|
||||
#endif
|
||||
|
@ -215,7 +215,7 @@ zend_module_entry gmp_module_entry = {
|
||||
|
||||
#ifdef COMPILE_DL_GMP
|
||||
#ifdef ZTS
|
||||
ZEND_TSRMLS_CACHE_DEFINE;
|
||||
ZEND_TSRMLS_CACHE_DEFINE();
|
||||
#endif
|
||||
ZEND_GET_MODULE(gmp)
|
||||
#endif
|
||||
@ -433,8 +433,7 @@ static HashTable *gmp_get_debug_info(zval *obj, int *is_temp) /* {{{ */
|
||||
zval zv;
|
||||
|
||||
*is_temp = 1;
|
||||
ALLOC_HASHTABLE(ht);
|
||||
zend_array_dup(ht, props);
|
||||
ht = zend_array_dup(props);
|
||||
|
||||
gmp_strval(&zv, gmpnum, 10);
|
||||
zend_hash_str_update(ht, "num", sizeof("num")-1, &zv);
|
||||
@ -560,7 +559,6 @@ static int gmp_serialize(zval *object, unsigned char **buffer, size_t *buf_len,
|
||||
smart_str buf = {0};
|
||||
zval zv;
|
||||
php_serialize_data_t serialize_data = (php_serialize_data_t) data;
|
||||
zend_array tmp_arr;
|
||||
|
||||
PHP_VAR_SERIALIZE_INIT(serialize_data);
|
||||
|
||||
@ -568,8 +566,7 @@ static int gmp_serialize(zval *object, unsigned char **buffer, size_t *buf_len,
|
||||
php_var_serialize(&buf, &zv, &serialize_data);
|
||||
zval_dtor(&zv);
|
||||
|
||||
ZVAL_ARR(&zv, &tmp_arr);
|
||||
tmp_arr.ht = *zend_std_get_properties(object);
|
||||
ZVAL_ARR(&zv, zend_std_get_properties(object));
|
||||
php_var_serialize(&buf, &zv, &serialize_data);
|
||||
|
||||
PHP_VAR_SERIALIZE_DESTROY(serialize_data);
|
||||
@ -633,7 +630,7 @@ exit:
|
||||
static ZEND_GINIT_FUNCTION(gmp)
|
||||
{
|
||||
#if defined(COMPILE_DL_GMP) && defined(ZTS)
|
||||
ZEND_TSRMLS_CACHE_UPDATE;
|
||||
ZEND_TSRMLS_CACHE_UPDATE();
|
||||
#endif
|
||||
gmp_globals->rand_initialized = 0;
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ ZEND_END_MODULE_GLOBALS(gmp)
|
||||
#ifdef ZTS
|
||||
#define GMPG(v) ZEND_TSRMG(gmp_globals_id, zend_gmp_globals *, v)
|
||||
#ifdef COMPILE_DL_GMP
|
||||
ZEND_TSRMLS_CACHE_EXTERN;
|
||||
ZEND_TSRMLS_CACHE_EXTERN();
|
||||
#endif
|
||||
#else
|
||||
#define GMPG(v) (gmp_globals.v)
|
||||
|
@ -165,7 +165,7 @@ zend_module_entry iconv_module_entry = {
|
||||
|
||||
#ifdef COMPILE_DL_ICONV
|
||||
#ifdef ZTS
|
||||
ZEND_TSRMLS_CACHE_DEFINE;
|
||||
ZEND_TSRMLS_CACHE_DEFINE();
|
||||
#endif
|
||||
ZEND_GET_MODULE(iconv)
|
||||
#endif
|
||||
@ -174,7 +174,7 @@ ZEND_GET_MODULE(iconv)
|
||||
static PHP_GINIT_FUNCTION(iconv)
|
||||
{
|
||||
#if defined(COMPILE_DL_ICONV) && defined(ZTS)
|
||||
ZEND_TSRMLS_CACHE_UPDATE;
|
||||
ZEND_TSRMLS_CACHE_UPDATE();
|
||||
#endif
|
||||
iconv_globals->input_encoding = NULL;
|
||||
iconv_globals->output_encoding = NULL;
|
||||
|
@ -75,7 +75,7 @@ ZEND_END_MODULE_GLOBALS(iconv)
|
||||
#ifdef ZTS
|
||||
# define ICONVG(v) ZEND_TSRMG(iconv_globals_id, zend_iconv_globals *, v)
|
||||
# ifdef COMPILE_DL_ICONV
|
||||
ZEND_TSRMLS_CACHE_EXTERN;
|
||||
ZEND_TSRMLS_CACHE_EXTERN();
|
||||
# endif
|
||||
#else
|
||||
# define ICONVG(v) (iconv_globals.v)
|
||||
|
@ -229,8 +229,8 @@ PHP_FUNCTION(ibase_blob_create)
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
ZEND_REGISTER_RESOURCE(return_value, ib_blob, le_blob);
|
||||
Z_ADDREF_P(return_value);
|
||||
RETVAL_RES(zend_register_resource(ib_blob, le_blob));
|
||||
Z_TRY_ADDREF_P(return_value);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -280,8 +280,8 @@ PHP_FUNCTION(ibase_blob_open)
|
||||
break;
|
||||
}
|
||||
|
||||
ZEND_REGISTER_RESOURCE(return_value, ib_blob, le_blob);
|
||||
Z_ADDREF_P(return_value);
|
||||
RETVAL_RES(zend_register_resource(ib_blob, le_blob));
|
||||
Z_TRY_ADDREF_P(return_value);
|
||||
return;
|
||||
|
||||
} while (0);
|
||||
@ -300,11 +300,11 @@ PHP_FUNCTION(ibase_blob_add)
|
||||
|
||||
RESET_ERRMSG;
|
||||
|
||||
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &blob_arg, &string_arg) == FAILURE) {
|
||||
WRONG_PARAM_COUNT;
|
||||
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr", &blob_arg, &string_arg)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ZEND_FETCH_RESOURCE(ib_blob, ibase_blob *, blob_arg, -1, "Interbase blob", le_blob);
|
||||
ib_blob = (ibase_blob *)zend_fetch_resource_ex(blob_arg, "Interbase blob", le_blob);
|
||||
|
||||
if (ib_blob->type != BLOB_INPUT) {
|
||||
_php_ibase_module_error("BLOB is not open for input");
|
||||
@ -321,25 +321,24 @@ PHP_FUNCTION(ibase_blob_add)
|
||||
Get len bytes data from open blob */
|
||||
PHP_FUNCTION(ibase_blob_get)
|
||||
{
|
||||
zval *blob_arg, *len_arg;
|
||||
zval *blob_arg;
|
||||
unsigned long len_arg;
|
||||
ibase_blob *ib_blob;
|
||||
|
||||
RESET_ERRMSG;
|
||||
|
||||
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &blob_arg, &len_arg) == FAILURE) {
|
||||
WRONG_PARAM_COUNT;
|
||||
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &blob_arg, &len_arg)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ZEND_FETCH_RESOURCE(ib_blob, ibase_blob *, blob_arg, -1, "Interbase blob", le_blob);
|
||||
ib_blob = (ibase_blob *)zend_fetch_resource_ex(blob_arg, "Interbase blob", le_blob);
|
||||
|
||||
if (ib_blob->type != BLOB_OUTPUT) {
|
||||
_php_ibase_module_error("BLOB is not open for output");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
convert_to_long_ex(len_arg);
|
||||
|
||||
if (_php_ibase_blob_get(return_value, ib_blob, Z_LVAL_P(len_arg)) != SUCCESS) {
|
||||
if (_php_ibase_blob_get(return_value, ib_blob, len_arg) != SUCCESS) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
@ -353,11 +352,11 @@ static void _php_ibase_blob_end(INTERNAL_FUNCTION_PARAMETERS, int bl_end) /* {{{
|
||||
|
||||
RESET_ERRMSG;
|
||||
|
||||
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &blob_arg) == FAILURE) {
|
||||
WRONG_PARAM_COUNT;
|
||||
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &blob_arg)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ZEND_FETCH_RESOURCE(ib_blob, ibase_blob *, blob_arg, -1, "Interbase blob", le_blob);
|
||||
ib_blob = (ibase_blob *)zend_fetch_resource_ex(blob_arg, "Interbase blob", le_blob);
|
||||
|
||||
if (bl_end == BLOB_CLOSE) { /* return id here */
|
||||
|
||||
|
@ -142,7 +142,7 @@ PHP_FUNCTION(ibase_wait_event)
|
||||
}
|
||||
|
||||
if (Z_TYPE(args[0]) == IS_RESOURCE) {
|
||||
if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link, ibase_db_link *, &args[0], -1, "InterBase link", le_link, le_plink)) {
|
||||
if ((ib_link = (ibase_db_link *)zend_fetch_resource2_ex(&args[0], "InterBase link", le_link, le_plink)) == NULL) {
|
||||
efree(args);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
@ -152,7 +152,7 @@ PHP_FUNCTION(ibase_wait_event)
|
||||
efree(args);
|
||||
WRONG_PARAM_COUNT;
|
||||
}
|
||||
if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link, ibase_db_link *, NULL, IBG(default_link), "InterBase link", le_link, le_plink)) {
|
||||
if ((ib_link = (ibase_db_link *)zend_fetch_resource2_ex(IBG(default_link), "InterBase link", le_link, le_plink)) == NULL) {
|
||||
efree(args);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
@ -293,7 +293,7 @@ PHP_FUNCTION(ibase_set_event_handler)
|
||||
cb_arg = &args[1];
|
||||
i = 2;
|
||||
|
||||
if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link, ibase_db_link *, &args[0], -1, "InterBase link", le_link, le_plink)) {
|
||||
if ((ib_link = (ibase_db_link *)zend_fetch_resource2_ex(&args[0], "InterBase link", le_link, le_plink)) == NULL) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@ -310,7 +310,7 @@ PHP_FUNCTION(ibase_set_event_handler)
|
||||
|
||||
cb_arg = &args[0];
|
||||
|
||||
if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link, ibase_db_link *, NULL, IBG(default_link), "InterBase link", le_link, le_plink)) {
|
||||
if ((ib_link = (ibase_db_link *)zend_fetch_resource2_ex(IBG(default_link), "InterBase link", le_link, le_plink)) == NULL) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
link_res_id = IBG(default_link);
|
||||
@ -356,8 +356,8 @@ PHP_FUNCTION(ibase_set_event_handler)
|
||||
event->event_next = ib_link->event_head;
|
||||
ib_link->event_head = event;
|
||||
|
||||
ZEND_REGISTER_RESOURCE(return_value, event, le_event);
|
||||
Z_ADDREF_P(return_value);
|
||||
RETVAL_RES(zend_register_resource(event, le_event));
|
||||
Z_TRY_ADDREF_P(return_value);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -372,7 +372,7 @@ PHP_FUNCTION(ibase_free_event_handler)
|
||||
if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "r", &event_arg)) {
|
||||
ibase_event *event;
|
||||
|
||||
ZEND_FETCH_RESOURCE(event, ibase_event *, event_arg, -1, "Interbase event", le_event);
|
||||
event = (ibase_event *)zend_fetch_resource_ex(event_arg, "Interbase event", le_event);
|
||||
|
||||
event->state = DEAD;
|
||||
|
||||
|
@ -910,8 +910,8 @@ static int _php_ibase_exec(INTERNAL_FUNCTION_PARAMETERS, ibase_result **ib_resul
|
||||
(*l)->trans = trans;
|
||||
(*l)->next = NULL;
|
||||
|
||||
ZEND_REGISTER_RESOURCE(return_value, trans, le_trans);
|
||||
Z_ADDREF_P(return_value);
|
||||
RETVAL_RES(zend_register_resource(trans, le_trans));
|
||||
Z_TRY_ADDREF_P(return_value);
|
||||
|
||||
return SUCCESS;
|
||||
|
||||
@ -1080,8 +1080,8 @@ PHP_FUNCTION(ibase_query)
|
||||
if (SUCCESS == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, 3, "rrs",
|
||||
&zlink, &ztrans, &query, &query_len)) {
|
||||
|
||||
ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link*, zlink, -1, LE_LINK, le_link, le_plink);
|
||||
ZEND_FETCH_RESOURCE(trans, ibase_trans*, ztrans, -1, LE_TRANS, le_trans);
|
||||
ib_link = (ibase_db_link*)zend_fetch_resource2_ex(zlink, LE_LINK, le_link, le_plink);
|
||||
trans = (ibase_trans*)zend_fetch_resource_ex(ztrans, LE_TRANS, le_trans);
|
||||
|
||||
trans_res_id = Z_RES_P(ztrans)->handle;
|
||||
bind_i = 3;
|
||||
@ -1131,8 +1131,8 @@ PHP_FUNCTION(ibase_query)
|
||||
ib_link->tr_list = NULL;
|
||||
ib_link->event_head = NULL;
|
||||
|
||||
ZEND_REGISTER_RESOURCE(return_value, ib_link, le_link);
|
||||
Z_ADDREF_P(return_value);
|
||||
RETVAL_RES(zend_register_resource(ib_link, le_link));
|
||||
Z_TRY_ADDREF_P(return_value);
|
||||
IBG(default_link) = Z_RES_P(return_value)->handle;
|
||||
++IBG(num_links);
|
||||
}
|
||||
@ -1142,7 +1142,7 @@ PHP_FUNCTION(ibase_query)
|
||||
case 0:
|
||||
if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() ? 1 : 0, "s", &query,
|
||||
&query_len)) {
|
||||
ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, NULL, IBG(default_link), LE_LINK,
|
||||
ib_link = (ibase_db_link *)zend_fetch_resource2_ex(IBG(default_link), LE_LINK,
|
||||
le_link, le_plink);
|
||||
|
||||
bind_i = 1;
|
||||
@ -1186,8 +1186,8 @@ PHP_FUNCTION(ibase_query)
|
||||
if (ib_query.statement_type != isc_info_sql_stmt_exec_procedure) {
|
||||
ib_query.stmt = NULL; /* keep stmt when free query */
|
||||
}
|
||||
ZEND_REGISTER_RESOURCE(return_value, result, le_result);
|
||||
Z_ADDREF_P(return_value);
|
||||
RETVAL_RES(zend_register_resource(result, le_result));
|
||||
Z_TRY_ADDREF_P(return_value);
|
||||
}
|
||||
} while (0);
|
||||
|
||||
@ -1211,7 +1211,7 @@ PHP_FUNCTION(ibase_affected_rows)
|
||||
}
|
||||
|
||||
if (!arg) {
|
||||
ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, NULL, IBG(default_link), LE_LINK, le_link, le_plink);
|
||||
ib_link = (ibase_db_link *)zend_fetch_resource2_ex(IBG(default_link), LE_LINK, le_link, le_plink);
|
||||
if (ib_link->tr_list == NULL || ib_link->tr_list->trans == NULL) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
@ -1220,7 +1220,7 @@ PHP_FUNCTION(ibase_affected_rows)
|
||||
/* one id was passed, could be db or trans id */
|
||||
_php_ibase_get_link_trans(INTERNAL_FUNCTION_PARAM_PASSTHRU, arg, &ib_link, &trans);
|
||||
if (trans == NULL) {
|
||||
ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, arg, -1, LE_LINK, le_link, le_plink);
|
||||
ib_link = (ibase_db_link *)zend_fetch_resource2_ex(arg, LE_LINK, le_link, le_plink);
|
||||
|
||||
if (ib_link->tr_list == NULL || ib_link->tr_list->trans == NULL) {
|
||||
RETURN_FALSE;
|
||||
@ -1268,7 +1268,7 @@ PHP_FUNCTION(ibase_num_rows)
|
||||
return;
|
||||
}
|
||||
|
||||
ZEND_FETCH_RESOURCE(ib_result, ibase_result *, &result_arg, -1, LE_RESULT, le_result);
|
||||
ib_result = (ibase_result *)zend_fetch_resource_ex(&result_arg, LE_RESULT, le_result);
|
||||
|
||||
if (isc_dsql_sql_info(IB_STATUS, &ib_result->stmt, sizeof(info_count), info_count, sizeof(result), result)) {
|
||||
_php_ibase_error();
|
||||
@ -1335,7 +1335,7 @@ static int _php_ibase_var_zval(zval *val, void *data, int type, int len, /* {{{
|
||||
#else
|
||||
if (scale == 0) {
|
||||
l = slprintf(string_data, sizeof(string_data), "%" LL_MASK "d", *(ISC_INT64 *) data);
|
||||
ZVAL_STRINGL(val,string_data,l,1);
|
||||
ZVAL_STRINGL(val,string_data,l);
|
||||
} else {
|
||||
ISC_INT64 n = *(ISC_INT64 *) data, f = scales[-scale];
|
||||
|
||||
@ -1346,7 +1346,7 @@ static int _php_ibase_var_zval(zval *val, void *data, int type, int len, /* {{{
|
||||
} else {
|
||||
l = slprintf(string_data, sizeof(string_data), "-0.%0*" LL_MASK "d", -scale, -n % f);
|
||||
}
|
||||
ZVAL_STRINGL(val,string_data,l,1);
|
||||
ZVAL_STRINGL(val,string_data,l);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
@ -1482,7 +1482,7 @@ static void _php_ibase_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int fetch_type)
|
||||
return;
|
||||
}
|
||||
|
||||
ZEND_FETCH_RESOURCE(ib_result, ibase_result *, result_arg, -1, LE_RESULT, le_result);
|
||||
ib_result = (ibase_result *)zend_fetch_resource_ex(result_arg, LE_RESULT, le_result);
|
||||
|
||||
if (ib_result->out_sqlda == NULL || !ib_result->has_more_rows) {
|
||||
RETURN_FALSE;
|
||||
@ -1698,7 +1698,7 @@ PHP_FUNCTION(ibase_name_result)
|
||||
return;
|
||||
}
|
||||
|
||||
ZEND_FETCH_RESOURCE(ib_result, ibase_result *, result_arg, -1, LE_RESULT, le_result);
|
||||
ib_result = (ibase_result *)zend_fetch_resource_ex(result_arg, LE_RESULT, le_result);
|
||||
|
||||
if (isc_dsql_set_cursor_name(IB_STATUS, &ib_result->stmt, name_arg, 0)) {
|
||||
_php_ibase_error();
|
||||
@ -1722,7 +1722,7 @@ PHP_FUNCTION(ibase_free_result)
|
||||
return;
|
||||
}
|
||||
|
||||
ZEND_FETCH_RESOURCE(ib_result, ibase_result *, result_arg, -1, LE_RESULT, le_result);
|
||||
ib_result = (ibase_result *)zend_fetch_resource_ex(result_arg, LE_RESULT, le_result);
|
||||
zend_list_delete(Z_RES_P(result_arg));
|
||||
RETURN_TRUE;
|
||||
}
|
||||
@ -1745,7 +1745,7 @@ PHP_FUNCTION(ibase_prepare)
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &query, &query_len) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, NULL, IBG(default_link), LE_LINK, le_link, le_plink);
|
||||
ib_link = (ibase_db_link *)zend_fetch_resource2_ex(IBG(default_link), LE_LINK, le_link, le_plink);
|
||||
} else if (ZEND_NUM_ARGS() == 2) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &link_arg, &query, &query_len) == FAILURE) {
|
||||
return;
|
||||
@ -1759,8 +1759,8 @@ PHP_FUNCTION(ibase_prepare)
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "rrs", &link_arg, &trans_arg, &query, &query_len) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, link_arg, -1, LE_LINK, le_link, le_plink);
|
||||
ZEND_FETCH_RESOURCE(trans, ibase_trans *, trans_arg, -1, LE_TRANS, le_trans);
|
||||
ib_link = (ibase_db_link *)zend_fetch_resource2_ex(link_arg, LE_LINK, le_link, le_plink);
|
||||
trans = (ibase_trans *)zend_fetch_resource_ex(trans_arg, LE_TRANS, le_trans);
|
||||
trans_res_id = Z_RES_P(trans_arg)->handle;
|
||||
}
|
||||
|
||||
@ -1774,8 +1774,8 @@ PHP_FUNCTION(ibase_prepare)
|
||||
efree(ib_query);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
ZEND_REGISTER_RESOURCE(return_value, ib_query, le_query);
|
||||
Z_ADDREF_P(return_value);
|
||||
RETVAL_RES(zend_register_resource(ib_query, le_query));
|
||||
Z_TRY_ADDREF_P(return_value);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -1796,7 +1796,7 @@ PHP_FUNCTION(ibase_execute)
|
||||
return;
|
||||
}
|
||||
|
||||
ZEND_FETCH_RESOURCE(ib_query, ibase_query *, query, -1, LE_QUERY, le_query);
|
||||
ib_query = (ibase_query *)zend_fetch_resource_ex(query, LE_QUERY, le_query);
|
||||
|
||||
do {
|
||||
int expected_n = ib_query->in_sqlda ? ib_query->in_sqlda->sqld : 0;
|
||||
@ -1849,8 +1849,8 @@ PHP_FUNCTION(ibase_execute)
|
||||
ret = zend_list_insert(result, le_result);
|
||||
ib_query->result_res_id = Z_RES_HANDLE_P(ret);
|
||||
ZVAL_COPY_VALUE(return_value, ret);
|
||||
Z_ADDREF_P(return_value);
|
||||
Z_ADDREF_P(return_value);
|
||||
Z_TRY_ADDREF_P(return_value);
|
||||
Z_TRY_ADDREF_P(return_value);
|
||||
}
|
||||
} while (0);
|
||||
}
|
||||
@ -1869,7 +1869,7 @@ PHP_FUNCTION(ibase_free_query)
|
||||
return;
|
||||
}
|
||||
|
||||
ZEND_FETCH_RESOURCE(ib_query, ibase_query *, query_arg, -1, LE_QUERY, le_query);
|
||||
ib_query = (ibase_query *)zend_fetch_resource_ex(query_arg, LE_QUERY, le_query);
|
||||
zend_list_close(Z_RES_P(query_arg));
|
||||
RETURN_TRUE;
|
||||
}
|
||||
@ -1893,13 +1893,13 @@ PHP_FUNCTION(ibase_num_fields)
|
||||
|
||||
if (type == le_query) {
|
||||
ibase_query *ib_query;
|
||||
|
||||
ZEND_FETCH_RESOURCE(ib_query, ibase_query *, result, -1, LE_QUERY, le_query);
|
||||
|
||||
ib_query = (ibase_query *)zend_fetch_resource_ex(result, LE_QUERY, le_query);
|
||||
sqlda = ib_query->out_sqlda;
|
||||
} else {
|
||||
ibase_result *ib_result;
|
||||
|
||||
ZEND_FETCH_RESOURCE(ib_result, ibase_result *, result, -1, LE_RESULT, le_result);
|
||||
ib_result = (ibase_result *)zend_fetch_resource_ex(result, LE_RESULT, le_result);
|
||||
sqlda = ib_result->out_sqlda;
|
||||
}
|
||||
|
||||
@ -2018,12 +2018,12 @@ PHP_FUNCTION(ibase_field_info)
|
||||
if (type == le_query) {
|
||||
ibase_query *ib_query;
|
||||
|
||||
ZEND_FETCH_RESOURCE(ib_query, ibase_query *, result_arg, -1, LE_QUERY, le_query);
|
||||
ib_query= (ibase_query *)zend_fetch_resource_ex(result_arg, LE_QUERY, le_query);
|
||||
sqlda = ib_query->out_sqlda;
|
||||
} else {
|
||||
ibase_result *ib_result;
|
||||
|
||||
ZEND_FETCH_RESOURCE(ib_result, ibase_result *, result_arg, -1, LE_RESULT, le_result);
|
||||
ib_result = (ibase_result *)zend_fetch_resource_ex(result_arg, LE_RESULT, le_result);
|
||||
sqlda = ib_result->out_sqlda;
|
||||
}
|
||||
|
||||
@ -2052,7 +2052,7 @@ PHP_FUNCTION(ibase_num_params)
|
||||
return;
|
||||
}
|
||||
|
||||
ZEND_FETCH_RESOURCE(ib_query, ibase_query *, result, -1, LE_QUERY, le_query);
|
||||
ib_query = (ibase_query *)zend_fetch_resource_ex(result, LE_QUERY, le_query);
|
||||
|
||||
if (ib_query->in_sqlda == NULL) {
|
||||
RETURN_LONG(0);
|
||||
@ -2076,7 +2076,7 @@ PHP_FUNCTION(ibase_param_info)
|
||||
return;
|
||||
}
|
||||
|
||||
ZEND_FETCH_RESOURCE(ib_query, ibase_query *, result_arg, -1, LE_QUERY, le_query);
|
||||
ib_query = (ibase_query *)zend_fetch_resource_ex(result_arg, LE_QUERY, le_query);
|
||||
|
||||
if (ib_query->in_sqlda == NULL) {
|
||||
RETURN_FALSE;
|
||||
|
@ -151,7 +151,7 @@ static void _php_ibase_user(INTERNAL_FUNCTION_PARAMETERS, char operation) /* {{{
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
ZEND_FETCH_RESOURCE(svm, ibase_service *, res, -1, "Interbase service manager handle",
|
||||
svm = (ibase_service *)zend_fetch_resource_ex(res, "Interbase service manager handle",
|
||||
le_service);
|
||||
|
||||
buf[0] = operation;
|
||||
@ -245,8 +245,8 @@ PHP_FUNCTION(ibase_service_attach)
|
||||
svm->hostname = estrdup(host);
|
||||
svm->username = estrdup(user);
|
||||
|
||||
ZEND_REGISTER_RESOURCE(return_value, svm, le_service);
|
||||
Z_ADDREF_P(return_value);
|
||||
RETVAL_RES(zend_register_resource(svm, le_service));
|
||||
Z_TRY_ADDREF_P(return_value);
|
||||
svm->res = Z_RES_P(return_value);
|
||||
}
|
||||
/* }}} */
|
||||
@ -437,7 +437,7 @@ static void _php_ibase_backup_restore(INTERNAL_FUNCTION_PARAMETERS, char operati
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
ZEND_FETCH_RESOURCE(svm, ibase_service *, res, -1,
|
||||
svm = (ibase_service *)zend_fetch_resource_ex(res,
|
||||
"Interbase service manager handle", le_service);
|
||||
|
||||
/* fill the param buffer */
|
||||
@ -500,7 +500,7 @@ static void _php_ibase_service_action(INTERNAL_FUNCTION_PARAMETERS, char svc_act
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
ZEND_FETCH_RESOURCE(svm, ibase_service *, res, -1,
|
||||
svm = (ibase_service *)zend_fetch_resource_ex(res,
|
||||
"Interbase service manager handle", le_service);
|
||||
|
||||
if (svc_action == isc_action_svc_db_stats) {
|
||||
@ -606,7 +606,7 @@ PHP_FUNCTION(ibase_server_info)
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
ZEND_FETCH_RESOURCE(svm, ibase_service *, res, -1,
|
||||
svm = (ibase_service *)zend_fetch_resource_ex(res,
|
||||
"Interbase service manager handle", le_service);
|
||||
|
||||
_php_ibase_service_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, svm, (char)action);
|
||||
|
@ -505,11 +505,11 @@ PHP_FUNCTION(ibase_errcode)
|
||||
void _php_ibase_error(void) /* {{{ */
|
||||
{
|
||||
char *s = IBG(errmsg);
|
||||
ISC_STATUS *statusp = IB_STATUS;
|
||||
const ISC_STATUS *statusp = IB_STATUS;
|
||||
|
||||
IBG(sql_code) = isc_sqlcode(IB_STATUS);
|
||||
|
||||
while ((s - IBG(errmsg)) < MAX_ERRMSG - (IBASE_MSGSIZE + 2) && isc_interprete(s, &statusp)) {
|
||||
while ((s - IBG(errmsg)) < MAX_ERRMSG - (IBASE_MSGSIZE + 2) && fb_interpret(s, MAX_ERRMSG, &statusp)) {
|
||||
strcat(IBG(errmsg), " ");
|
||||
s = IBG(errmsg) + strlen(IBG(errmsg));
|
||||
}
|
||||
@ -553,7 +553,7 @@ void _php_ibase_get_link_trans(INTERNAL_FUNCTION_PARAMETERS, /* {{{ */
|
||||
/* Transaction resource: make sure it refers to one link only, then
|
||||
fetch it; database link is stored in ib_trans->db_link[]. */
|
||||
IBDEBUG("Type is le_trans");
|
||||
ZEND_FETCH_RESOURCE(*trans, ibase_trans *, link_id, -1, LE_TRANS, le_trans);
|
||||
*trans = (ibase_trans *)zend_fetch_resource_ex(link_id, LE_TRANS, le_trans);
|
||||
if ((*trans)->link_cnt > 1) {
|
||||
_php_ibase_module_error("Link id is ambiguous: transaction spans multiple connections."
|
||||
);
|
||||
@ -565,7 +565,7 @@ void _php_ibase_get_link_trans(INTERNAL_FUNCTION_PARAMETERS, /* {{{ */
|
||||
IBDEBUG("Type is le_[p]link or id not found");
|
||||
/* Database link resource, use default transaction. */
|
||||
*trans = NULL;
|
||||
ZEND_FETCH_RESOURCE2(*ib_link, ibase_db_link *, link_id, -1, LE_LINK, le_link, le_plink);
|
||||
*ib_link = (ibase_db_link *)zend_fetch_resource2_ex(link_id, LE_LINK, le_link, le_plink);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -941,7 +941,7 @@ static void _php_ibase_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) /*
|
||||
xlink->gc.refcount++;
|
||||
xlink->gc.refcount++;
|
||||
IBG(default_link) = xlink->handle;
|
||||
RETURN_RES(xlink);
|
||||
RETVAL_RES(xlink);
|
||||
} else {
|
||||
zend_hash_str_del(&EG(regular_list), hash, sizeof(hash)-1);
|
||||
}
|
||||
@ -961,7 +961,7 @@ static void _php_ibase_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) /*
|
||||
/* check if connection has timed out */
|
||||
ib_link = (ibase_db_link *) le->ptr;
|
||||
if (!isc_database_info(status, &ib_link->handle, sizeof(info), info, sizeof(result), result)) {
|
||||
ZEND_REGISTER_RESOURCE(return_value, ib_link, le_plink);
|
||||
RETVAL_RES(zend_register_resource(ib_link, le_plink));
|
||||
break;
|
||||
}
|
||||
zend_hash_str_del(&EG(persistent_list), hash, sizeof(hash)-1);
|
||||
@ -982,7 +982,7 @@ static void _php_ibase_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) /*
|
||||
/* use non-persistent if allowed number of persistent links is exceeded */
|
||||
if (!persistent || ((l = INI_INT("ibase.max_persistent") != -1) && IBG(num_persistent) >= l)) {
|
||||
ib_link = (ibase_db_link *) emalloc(sizeof(ibase_db_link));
|
||||
ZEND_REGISTER_RESOURCE(return_value, ib_link, le_link);
|
||||
RETVAL_RES(zend_register_resource(ib_link, le_link));
|
||||
} else {
|
||||
zend_resource new_le;
|
||||
|
||||
@ -999,7 +999,7 @@ static void _php_ibase_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) /*
|
||||
free(ib_link);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
ZEND_REGISTER_RESOURCE(return_value, ib_link, le_plink);
|
||||
RETVAL_RES(zend_register_resource(ib_link, le_plink));
|
||||
++IBG(num_persistent);
|
||||
}
|
||||
ib_link->handle = db_handle;
|
||||
@ -1024,8 +1024,8 @@ static void _php_ibase_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) /*
|
||||
}
|
||||
}
|
||||
IBG(default_link) = Z_RES_P(return_value)->handle;
|
||||
Z_ADDREF_P(return_value);
|
||||
Z_ADDREF_P(return_value);
|
||||
Z_TRY_ADDREF_P(return_value);
|
||||
Z_TRY_ADDREF_P(return_value);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -1067,7 +1067,7 @@ PHP_FUNCTION(ibase_close)
|
||||
link_id = Z_RES_P(link_arg)->handle;
|
||||
}
|
||||
|
||||
ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, link_arg, link_id, LE_LINK, le_link, le_plink);
|
||||
ib_link = (ibase_db_link *)zend_fetch_resource2_ex(link_arg, LE_LINK, le_link, le_plink);
|
||||
if (!link_arg) {
|
||||
link_arg = zend_hash_index_find(&EG(regular_list), link_id);
|
||||
zend_list_delete(Z_RES_P(link_arg));
|
||||
@ -1105,7 +1105,7 @@ PHP_FUNCTION(ibase_drop_db)
|
||||
link_id = Z_RES_P(link_arg)->handle;
|
||||
}
|
||||
|
||||
ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, link_arg, link_id, LE_LINK, le_link, le_plink);
|
||||
ib_link = (ibase_db_link *)zend_fetch_resource2_ex(link_arg, LE_LINK, le_link, le_plink);
|
||||
|
||||
if (isc_drop_database(IB_STATUS, &ib_link->handle)) {
|
||||
_php_ibase_error();
|
||||
@ -1168,7 +1168,7 @@ PHP_FUNCTION(ibase_trans)
|
||||
|
||||
if (Z_TYPE(args[i]) == IS_RESOURCE) {
|
||||
|
||||
if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link[link_cnt], ibase_db_link *, &args[i], -1, LE_LINK, le_link, le_plink)) {
|
||||
if ((ib_link[link_cnt] = (ibase_db_link *)zend_fetch_resource2_ex(&args[i], LE_LINK, le_link, le_plink)) == NULL) {
|
||||
efree(teb);
|
||||
efree(tpb);
|
||||
efree(ib_link);
|
||||
@ -1236,7 +1236,7 @@ PHP_FUNCTION(ibase_trans)
|
||||
|
||||
if (link_cnt == 0) {
|
||||
link_cnt = 1;
|
||||
if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link[0], ibase_db_link *, NULL, IBG(default_link), LE_LINK, le_link, le_plink)) {
|
||||
if ((ib_link[0] = (ibase_db_link *)zend_fetch_resource2_ex(IBG(default_link), LE_LINK, le_link, le_plink)) == NULL) {
|
||||
efree(ib_link);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
@ -1273,8 +1273,8 @@ PHP_FUNCTION(ibase_trans)
|
||||
(*l)->next = NULL;
|
||||
}
|
||||
efree(ib_link);
|
||||
ZEND_REGISTER_RESOURCE(return_value, ib_trans, le_trans);
|
||||
Z_ADDREF_P(return_value);
|
||||
RETVAL_RES(zend_register_resource(ib_trans, le_trans));
|
||||
Z_TRY_ADDREF_P(return_value);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -1330,7 +1330,7 @@ static void _php_ibase_trans_end(INTERNAL_FUNCTION_PARAMETERS, int commit) /* {{
|
||||
}
|
||||
|
||||
if (ZEND_NUM_ARGS() == 0) {
|
||||
ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, NULL, IBG(default_link), LE_LINK, le_link, le_plink);
|
||||
ib_link = (ibase_db_link *)zend_fetch_resource2_ex(IBG(default_link), LE_LINK, le_link, le_plink);
|
||||
if (ib_link->tr_list == NULL || ib_link->tr_list->trans == NULL) {
|
||||
/* this link doesn't have a default transaction */
|
||||
_php_ibase_module_error("Default link has no default transaction");
|
||||
@ -1340,10 +1340,10 @@ static void _php_ibase_trans_end(INTERNAL_FUNCTION_PARAMETERS, int commit) /* {{
|
||||
} else {
|
||||
/* one id was passed, could be db or trans id */
|
||||
if (Z_RES_P(arg)->type == le_trans) {
|
||||
ZEND_FETCH_RESOURCE(trans, ibase_trans *, arg, -1, LE_TRANS, le_trans);
|
||||
trans = (ibase_trans *)zend_fetch_resource_ex(arg, LE_TRANS, le_trans);
|
||||
res_id = Z_RES_P(arg)->handle;
|
||||
} else {
|
||||
ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, arg, -1, LE_LINK, le_link, le_plink);
|
||||
ib_link = (ibase_db_link *)zend_fetch_resource2_ex(arg, LE_LINK, le_link, le_plink);
|
||||
|
||||
if (ib_link->tr_list == NULL || ib_link->tr_list->trans == NULL) {
|
||||
/* this link doesn't have a default transaction */
|
||||
@ -1467,7 +1467,7 @@ PHP_FUNCTION(ibase_gen_id)
|
||||
int l;
|
||||
|
||||
l = spprintf(&res, 0, "%" LL_MASK "d", result);
|
||||
RETURN_STRINGL(res, l, 0);
|
||||
RETURN_STRINGL(res, l);
|
||||
}
|
||||
#endif
|
||||
RETURN_LONG((long)result);
|
||||
|
@ -101,7 +101,7 @@ typedef struct event {
|
||||
char **events;
|
||||
char *event_buffer, *result_buffer;
|
||||
zval callback;
|
||||
void **thread_ctx;
|
||||
void *thread_ctx;
|
||||
struct event *event_next;
|
||||
enum event_state { NEW, ACTIVE, DEAD } state;
|
||||
} ibase_event;
|
||||
@ -128,7 +128,14 @@ enum php_interbase_option {
|
||||
};
|
||||
|
||||
#ifdef ZTS
|
||||
#define IBG(v) TSRMG(ibase_globals_id, zend_ibase_globals *, v)
|
||||
#else
|
||||
#endif
|
||||
|
||||
#ifdef ZTS
|
||||
# define IBG(v) ZEND_TSRMG(ibase_globals_id, zend_ibase_globals *, v)
|
||||
# ifdef COMPILE_DL_INTERBASE
|
||||
ZEND_TSRMLS_CACHE_EXTERN();
|
||||
# endif
|
||||
#else
|
||||
#define IBG(v) (ibase_globals.v)
|
||||
#endif
|
||||
@ -155,9 +162,9 @@ void _php_ibase_module_error(char *, ...)
|
||||
|
||||
/* determine if a resource is a link or transaction handle */
|
||||
#define PHP_IBASE_LINK_TRANS(zv, lh, th) \
|
||||
do { if (!zv) { \
|
||||
ZEND_FETCH_RESOURCE2(lh, ibase_db_link *, NULL, IBG(default_link), \
|
||||
"InterBase link", le_link, le_plink) } \
|
||||
do { if (!zv) { \
|
||||
lh = (ibase_db_link *)zend_fetch_resource2(IBG(default_link), \
|
||||
"InterBase link", le_link, le_plink); } \
|
||||
else \
|
||||
_php_ibase_get_link_trans(INTERNAL_FUNCTION_PARAM_PASSTHRU, zv, &lh, &th); \
|
||||
if (SUCCESS != _php_ibase_def_trans(lh, &th)) { RETURN_FALSE; } \
|
||||
|
@ -148,30 +148,20 @@ U_CFUNC PHP_FUNCTION(breakiter_get_text)
|
||||
|
||||
U_CFUNC PHP_FUNCTION(breakiter_set_text)
|
||||
{
|
||||
char *text;
|
||||
size_t text_len;
|
||||
UText *ut = NULL;
|
||||
zval *textzv;
|
||||
zend_string *text;
|
||||
BREAKITER_METHOD_INIT_VARS;
|
||||
object = getThis();
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s",
|
||||
&text, &text_len) == FAILURE) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &text) == FAILURE) {
|
||||
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
|
||||
"breakiter_set_text: bad arguments", 0);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
int res = zend_get_parameters_ex(1, &textzv);
|
||||
assert(res == SUCCESS);
|
||||
|
||||
BREAKITER_METHOD_FETCH_OBJECT;
|
||||
|
||||
/* assert it's safe to use text and text_len because zpp changes the
|
||||
* arguments in the stack */
|
||||
assert(text == Z_STRVAL_P(textzv));
|
||||
|
||||
ut = utext_openUTF8(ut, text, text_len, BREAKITER_ERROR_CODE_P(bio));
|
||||
ut = utext_openUTF8(ut, text->val, text->len, BREAKITER_ERROR_CODE_P(bio));
|
||||
INTL_CTOR_CHECK_STATUS(bio, "breakiter_set_text: error opening UText");
|
||||
|
||||
bio->biter->setText(ut, BREAKITER_ERROR_CODE(bio));
|
||||
@ -183,7 +173,7 @@ U_CFUNC PHP_FUNCTION(breakiter_set_text)
|
||||
* keep the string buffer around by holding a reference to its zval. This
|
||||
* also allows a faste implementation of getText() */
|
||||
zval_ptr_dtor(&bio->text);
|
||||
ZVAL_COPY(&bio->text, textzv);
|
||||
ZVAL_STR_COPY(&bio->text, text);
|
||||
|
||||
RETURN_TRUE;
|
||||
}
|
||||
@ -272,7 +262,7 @@ U_CFUNC PHP_FUNCTION(breakiter_next)
|
||||
no_arg_version = true;
|
||||
} else if (ZEND_NUM_ARGS() == 1) {
|
||||
zval *arg;
|
||||
int res = zend_get_parameters_ex(1, &arg);
|
||||
int res = zend_parse_parameters(ZEND_NUM_ARGS(), "z", &arg);
|
||||
assert(res == SUCCESS);
|
||||
if (Z_TYPE_P(arg) == IS_NULL) {
|
||||
no_arg_version = true;
|
||||
|
@ -86,8 +86,9 @@ U_CFUNC PHP_FUNCTION(datefmt_format_object)
|
||||
//nothing
|
||||
} else if (Z_TYPE_P(format) == IS_ARRAY) {
|
||||
HashTable *ht = Z_ARRVAL_P(format);
|
||||
HashPosition pos = {0};
|
||||
uint32_t idx;
|
||||
zval *z;
|
||||
|
||||
if (zend_hash_num_elements(ht) != 2) {
|
||||
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
|
||||
"datefmt_format_object: bad format; if array, it must have "
|
||||
@ -95,9 +96,15 @@ U_CFUNC PHP_FUNCTION(datefmt_format_object)
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
zend_hash_internal_pointer_reset_ex(ht, &pos);
|
||||
z = zend_hash_get_current_data_ex(ht, &pos);
|
||||
if (!valid_format(z)) {
|
||||
idx = 0;
|
||||
while (idx < ht->nNumUsed) {
|
||||
z = &ht->arData[idx].val;
|
||||
if (Z_TYPE_P(z) != IS_UNDEF) {
|
||||
break;
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
if (idx >= ht->nNumUsed || !valid_format(z)) {
|
||||
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
|
||||
"datefmt_format_object: bad format; the date format (first "
|
||||
"element of the array) is not valid", 0);
|
||||
@ -105,9 +112,15 @@ U_CFUNC PHP_FUNCTION(datefmt_format_object)
|
||||
}
|
||||
dateStyle = (DateFormat::EStyle)Z_LVAL_P(z);
|
||||
|
||||
zend_hash_move_forward_ex(ht, &pos);
|
||||
z = zend_hash_get_current_data_ex(ht, &pos);
|
||||
if (!valid_format(z)) {
|
||||
idx++;
|
||||
while (idx < ht->nNumUsed) {
|
||||
z = &ht->arData[idx].val;
|
||||
if (Z_TYPE_P(z) != IS_UNDEF) {
|
||||
break;
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
if (idx >= ht->nNumUsed || !valid_format(z)) {
|
||||
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
|
||||
"datefmt_format_object: bad format; the time format ("
|
||||
"second element of the array) is not valid", 0);
|
||||
|
@ -895,7 +895,7 @@ zend_module_entry intl_module_entry = {
|
||||
|
||||
#ifdef COMPILE_DL_INTL
|
||||
#ifdef ZTS
|
||||
ZEND_TSRMLS_CACHE_DEFINE;
|
||||
ZEND_TSRMLS_CACHE_DEFINE();
|
||||
#endif
|
||||
ZEND_GET_MODULE( intl )
|
||||
#endif
|
||||
@ -904,7 +904,7 @@ ZEND_GET_MODULE( intl )
|
||||
static PHP_GINIT_FUNCTION(intl)
|
||||
{
|
||||
#if defined(COMPILE_DL_INTL) && defined(ZTS)
|
||||
ZEND_TSRMLS_CACHE_UPDATE;
|
||||
ZEND_TSRMLS_CACHE_UPDATE();
|
||||
#endif
|
||||
memset( intl_globals, 0, sizeof(zend_intl_globals) );
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ ZEND_END_MODULE_GLOBALS(intl)
|
||||
#ifdef ZTS
|
||||
#define INTL_G(v) ZEND_TSRMG(intl_globals_id, zend_intl_globals *, v)
|
||||
#ifdef COMPILE_DL_INTL
|
||||
ZEND_TSRMLS_CACHE_EXTERN;
|
||||
ZEND_TSRMLS_CACHE_EXTERN();
|
||||
#endif
|
||||
#else
|
||||
#define INTL_G(v) (intl_globals.v)
|
||||
|
@ -1,76 +1,16 @@
|
||||
json 1.2.0
|
||||
JSON
|
||||
==========
|
||||
|
||||
|
||||
This extension implements the JavaScript Object Notation (JSON)
|
||||
data-interchange format as specified in [0].
|
||||
data-interchange format as specified in RFC 7159
|
||||
|
||||
Two functions are implemented: encoding and decoding. The decoding
|
||||
is handled by a parser based on JSON_checker[1] by Douglas Crockford.
|
||||
The parser is implemented using re2c and Bison. The used versions
|
||||
of both tools for generating files in the repository are following:
|
||||
|
||||
re2c 0.13.7.5
|
||||
Bison 3.0.4
|
||||
|
||||
Function overview
|
||||
-----------------
|
||||
|
||||
string json_encode ( mixed value )
|
||||
|
||||
json_encode returns a string containing the JSON representation of value.
|
||||
value can be any type except a resource.
|
||||
|
||||
mixed json_decode ( string json, [bool assoc] )
|
||||
|
||||
json_decode takes a JSON string and converts it into a PHP variable.
|
||||
When assoc is given, and evaluates to TRUE, json_decode() will return
|
||||
any objects as associative arrays.
|
||||
|
||||
|
||||
Example usage
|
||||
-------------
|
||||
|
||||
$arr = array("a"=>1,"b"=>2,"c"=>3,"d"=>4,"e"=>5);
|
||||
echo json_encode($arr);
|
||||
|
||||
---> {"a":1,"b":2,"c":3,"d":4,"e":5}
|
||||
|
||||
$json = '{"a":1,"b":2,"c":3,"d":4,"e":5}';
|
||||
var_dump(json_decode($json));
|
||||
|
||||
---> object(stdClass)#1 (5) {
|
||||
["a"]=>
|
||||
int(1)
|
||||
["b"]=>
|
||||
int(2)
|
||||
["c"]=>
|
||||
int(3)
|
||||
["d"]=>
|
||||
int(4)
|
||||
["e"]=>
|
||||
int(5)
|
||||
}
|
||||
|
||||
$json = '{"a":1,"b":2,"c":3,"d":4,"e":5}';
|
||||
var_dump(json_decode($json, true));
|
||||
|
||||
---> array(5) {
|
||||
["a"]=>
|
||||
int(1)
|
||||
["b"]=>
|
||||
int(2)
|
||||
["c"]=>
|
||||
int(3)
|
||||
["d"]=>
|
||||
int(4)
|
||||
["e"]=>
|
||||
int(5)
|
||||
}
|
||||
|
||||
|
||||
Authors
|
||||
-------
|
||||
|
||||
Omar Kilani <omar@php.net>
|
||||
|
||||
|
||||
---
|
||||
|
||||
[0] http://www.crockford.com/JSON/draft-jsonorg-json-00.txt
|
||||
[1] http://www.crockford.com/JSON/JSON_checker/
|
||||
It is recommended to do all contributions to the JSON extension
|
||||
through the Github Pull Requests and preferably ping @bukka
|
||||
who maintains the extension.
|
||||
|
@ -134,7 +134,7 @@ static PHP_MINIT_FUNCTION(json)
|
||||
static PHP_GINIT_FUNCTION(json)
|
||||
{
|
||||
#if defined(COMPILE_DL_JSON) && defined(ZTS)
|
||||
ZEND_TSRMLS_CACHE_UPDATE;
|
||||
ZEND_TSRMLS_CACHE_UPDATE();
|
||||
#endif
|
||||
json_globals->encoder_depth = 0;
|
||||
json_globals->error_code = 0;
|
||||
@ -165,7 +165,7 @@ zend_module_entry json_module_entry = {
|
||||
|
||||
#ifdef COMPILE_DL_JSON
|
||||
#ifdef ZTS
|
||||
ZEND_TSRMLS_CACHE_DEFINE;
|
||||
ZEND_TSRMLS_CACHE_DEFINE();
|
||||
#endif
|
||||
ZEND_GET_MODULE(json)
|
||||
#endif
|
||||
|
1860
ext/json/json_parser.tab.c
Normal file
1860
ext/json/json_parser.tab.c
Normal file
File diff suppressed because it is too large
Load Diff
95
ext/json/json_parser.tab.h
Normal file
95
ext/json/json_parser.tab.h
Normal file
@ -0,0 +1,95 @@
|
||||
/* A Bison parser, made by GNU Bison 3.0.4. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
under terms of your choice, so long as that work isn't itself a
|
||||
parser generator using the skeleton or a modified version thereof
|
||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||
the parser skeleton itself, you may (at your option) remove this
|
||||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
#ifndef YY_PHP_JSON_YY_HOME_JAKUB_PROG_PHP_MASTER_EXT_JSON_JSON_PARSER_TAB_H_INCLUDED
|
||||
# define YY_PHP_JSON_YY_HOME_JAKUB_PROG_PHP_MASTER_EXT_JSON_JSON_PARSER_TAB_H_INCLUDED
|
||||
/* Debug traces. */
|
||||
#ifndef YYDEBUG
|
||||
# define YYDEBUG 0
|
||||
#endif
|
||||
#if YYDEBUG
|
||||
extern int php_json_yydebug;
|
||||
#endif
|
||||
|
||||
/* Token type. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
enum yytokentype
|
||||
{
|
||||
PHP_JSON_T_NUL = 258,
|
||||
PHP_JSON_T_TRUE = 259,
|
||||
PHP_JSON_T_FALSE = 260,
|
||||
PHP_JSON_T_INT = 261,
|
||||
PHP_JSON_T_DOUBLE = 262,
|
||||
PHP_JSON_T_STRING = 263,
|
||||
PHP_JSON_T_ESTRING = 264,
|
||||
PHP_JSON_T_EOI = 265,
|
||||
PHP_JSON_T_ERROR = 266
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
#define PHP_JSON_T_NUL 258
|
||||
#define PHP_JSON_T_TRUE 259
|
||||
#define PHP_JSON_T_FALSE 260
|
||||
#define PHP_JSON_T_INT 261
|
||||
#define PHP_JSON_T_DOUBLE 262
|
||||
#define PHP_JSON_T_STRING 263
|
||||
#define PHP_JSON_T_ESTRING 264
|
||||
#define PHP_JSON_T_EOI 265
|
||||
#define PHP_JSON_T_ERROR 266
|
||||
|
||||
/* Value type. */
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
|
||||
union YYSTYPE
|
||||
{
|
||||
|
||||
|
||||
zval value;
|
||||
struct {
|
||||
zval key;
|
||||
zval val;
|
||||
} pair;
|
||||
|
||||
|
||||
};
|
||||
|
||||
typedef union YYSTYPE YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
int php_json_yyparse (php_json_parser *parser);
|
||||
|
||||
#endif /* !YY_PHP_JSON_YY_HOME_JAKUB_PROG_PHP_MASTER_EXT_JSON_JSON_PARSER_TAB_H_INCLUDED */
|
@ -67,7 +67,6 @@ int json_yydebug = 1;
|
||||
%type <pair> pair
|
||||
|
||||
%destructor { zval_dtor(&$$); } <value>
|
||||
%destructor { zend_hash_destroy($$); FREE_HASHTABLE($$); } <ht>
|
||||
%destructor { zval_dtor(&$$.key); zval_dtor(&$$.val); } <pair>
|
||||
|
||||
%code {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -81,7 +81,7 @@ static int php_json_ucs2_to_int(php_json_scanner *s, int size)
|
||||
return php_json_ucs2_to_int_ex(s, size, 1);
|
||||
}
|
||||
|
||||
void php_json_scanner_init(php_json_scanner *s, char *str, int str_len, long options)
|
||||
void php_json_scanner_init(php_json_scanner *s, char *str, size_t str_len, int options)
|
||||
{
|
||||
s->cursor = (php_json_ctype *) str;
|
||||
s->limit = (php_json_ctype *) str + str_len;
|
||||
@ -171,7 +171,7 @@ std:
|
||||
}
|
||||
}
|
||||
if (!bigint) {
|
||||
ZVAL_LONG(&s->value, strtol((char *) s->token, NULL, 10));
|
||||
ZVAL_LONG(&s->value, ZEND_STRTOL((char *) s->token, NULL, 10));
|
||||
return PHP_JSON_T_INT;
|
||||
} else if (s->options & PHP_JSON_BIGINT_AS_STRING) {
|
||||
ZVAL_STRINGL(&s->value, (char *) s->token, s->cursor - s->token);
|
||||
|
@ -1,152 +0,0 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
<!DOCTYPE package SYSTEM "../pear/package.dtd">
|
||||
<package>
|
||||
<dep type="php" rel="ge" version="4.3.0" optional="no"/>
|
||||
<name>json</name>
|
||||
<summary>JavaScript Object Notation</summary>
|
||||
<maintainers>
|
||||
<maintainer>
|
||||
<user>omar</user>
|
||||
<name>Omar Kilani</name>
|
||||
<email>omar@php.net</email>
|
||||
<role>lead</role>
|
||||
</maintainer>
|
||||
</maintainers>
|
||||
<description>
|
||||
Support for JSON (JavaScript Object Notation) serialization.
|
||||
</description>
|
||||
<license>PHP 3.01</license>
|
||||
<release>
|
||||
<state>stable</state>
|
||||
<version>1.2.1</version>
|
||||
<date>2006-03-18</date>
|
||||
<notes>
|
||||
Fix PECL bug #7147 - rework handling of comma insertion while encoding.
|
||||
Add tests to package.xml
|
||||
</notes>
|
||||
</release>
|
||||
<configureoptions>
|
||||
</configureoptions>
|
||||
<filelist>
|
||||
<file role="doc" name="README" />
|
||||
<file role="src" name="config.m4" />
|
||||
<file role="src" name="config.w32" />
|
||||
<file role="src" name="json.dsp" />
|
||||
<file role="src" name="json.c" />
|
||||
<file role="src" name="JSON_parser.c" />
|
||||
<file role="src" name="JSON_parser.h" />
|
||||
<file role="src" name="php_json.h" />
|
||||
<file role="src" name="utf8_decode.c" />
|
||||
<file role="src" name="utf8_decode.h" />
|
||||
<file role="src" name="utf8_to_utf16.c" />
|
||||
<file role="src" name="utf8_to_utf16.h" />
|
||||
<dir role="test" name="tests">
|
||||
<file role="test" name="fail001.phpt" />
|
||||
<file role="test" name="pass001.phpt" />
|
||||
<file role="test" name="pass001.1.phpt" />
|
||||
<file role="test" name="pass002.phpt" />
|
||||
<file role="test" name="pass003.phpt" />
|
||||
</dir>
|
||||
</filelist>
|
||||
<changelog>
|
||||
<release>
|
||||
<state>stable</state>
|
||||
<version>1.0.0</version>
|
||||
<date>2005-04-01</date>
|
||||
<notes>
|
||||
Initial release.
|
||||
</notes>
|
||||
</release>
|
||||
<release>
|
||||
<state>stable</state>
|
||||
<version>1.0.1</version>
|
||||
<date>2005-06-10</date>
|
||||
<notes>
|
||||
Fixed non-linear and mixed type array index issues, fixed issues with escaping \\, forked json-c and added Unicode support.
|
||||
</notes>
|
||||
</release>
|
||||
<release>
|
||||
<state>stable</state>
|
||||
<version>1.0.2</version>
|
||||
<date>2005-06-11</date>
|
||||
<notes>
|
||||
Fixed issues with object reference counts under PHP4.
|
||||
</notes>
|
||||
</release>
|
||||
<release>
|
||||
<state>stable</state>
|
||||
<version>1.0.3</version>
|
||||
<date>2005-06-15</date>
|
||||
<notes>
|
||||
Fixed json-c string corruption issues under Mac OS X and FreeBSD.
|
||||
</notes>
|
||||
</release>
|
||||
<release>
|
||||
<state>stable</state>
|
||||
<version>1.0.4</version>
|
||||
<date>2005-06-15</date>
|
||||
<notes>
|
||||
Changes in 1.0.4 released with 1.0.5.
|
||||
</notes>
|
||||
</release>
|
||||
<release>
|
||||
<state>stable</state>
|
||||
<version>1.0.5</version>
|
||||
<date>2005-06-16</date>
|
||||
<notes>
|
||||
Changed spacing in json-c encoding, added optional assoc (boolean) parameter to json_decode to decode as associative array instead of object, fixed issues with escaping /.
|
||||
</notes>
|
||||
</release>
|
||||
<release>
|
||||
<state>stable</state>
|
||||
<version>1.0.6</version>
|
||||
<date>2005-08-05</date>
|
||||
<notes>
|
||||
Fixed issues with exporting private and protected class members.
|
||||
</notes>
|
||||
</release>
|
||||
<release>
|
||||
<state>stable</state>
|
||||
<version>1.0.7</version>
|
||||
<date>2005-09-07</date>
|
||||
<notes>
|
||||
Fixed issues with negative array keys, modified json-c to return an error on unquoted object key names instead of going into an infinite loop.
|
||||
</notes>
|
||||
</release>
|
||||
<release>
|
||||
<state>stable</state>
|
||||
<version>1.0.8</version>
|
||||
<date>2005-12-01</date>
|
||||
<notes>
|
||||
Changed license to LGPL, modified build system to allow static compilation into PHP, added strndup check for json-c.
|
||||
</notes>
|
||||
</release>
|
||||
<release>
|
||||
<state>stable</state>
|
||||
<version>1.1.0</version>
|
||||
<date>2005-12-04</date>
|
||||
<notes>
|
||||
Port to Win32.
|
||||
</notes>
|
||||
</release>
|
||||
<release>
|
||||
<state>stable</state>
|
||||
<version>1.1.1</version>
|
||||
<date>2006-01-12</date>
|
||||
<notes>
|
||||
Cleanup and TSRM performance fixes by rasmus.
|
||||
</notes>
|
||||
</release>
|
||||
<release>
|
||||
<state>stable</state>
|
||||
<version>1.2.0</version>
|
||||
<date>2006-03-15</date>
|
||||
<notes>
|
||||
Complete rewrite using JSON_checker as the base for the parser. Implements the JSON specification. 3-8x faster on encodes and 1.2x-4x faster on decodes.
|
||||
</notes>
|
||||
</release>
|
||||
</changelog>
|
||||
</package>
|
||||
<!--
|
||||
vim:et:ts=1:sw=1
|
||||
-->
|
@ -22,7 +22,7 @@
|
||||
#ifndef PHP_JSON_H
|
||||
#define PHP_JSON_H
|
||||
|
||||
#define PHP_JSON_VERSION "1.2.1"
|
||||
#define PHP_JSON_VERSION "1.4.0"
|
||||
#include "zend_smart_str_public.h"
|
||||
|
||||
extern zend_module_entry json_module_entry;
|
||||
|
@ -32,15 +32,15 @@ typedef struct _php_json_scanner {
|
||||
php_json_ctype *ctxmarker; /* marker position for context backtracking */
|
||||
php_json_ctype *str_start; /* start position of the string */
|
||||
php_json_ctype *pstr; /* string pointer for escapes conversion */
|
||||
zval value; /* value */
|
||||
int str_esc; /* number of extra characters for escaping */
|
||||
int state; /* condition state */
|
||||
zval value; /* value */
|
||||
long options; /* options */
|
||||
int options; /* options */
|
||||
php_json_error_code errcode; /* error type if there is an error */
|
||||
} php_json_scanner;
|
||||
|
||||
|
||||
void php_json_scanner_init(php_json_scanner *scanner, char *str, int str_len, long options);
|
||||
void php_json_scanner_init(php_json_scanner *scanner, char *str, size_t str_len, int options);
|
||||
int php_json_scan(php_json_scanner *s);
|
||||
|
||||
#endif /* PHP_JSON_SCANNER_H */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Generated by re2c 0.13.5 */
|
||||
/* Generated by re2c 0.13.7.5 */
|
||||
|
||||
enum YYCONDTYPE {
|
||||
yycJS,
|
||||
|
@ -80,7 +80,7 @@ static zend_class_entry *libxmlerror_class_entry;
|
||||
/* {{{ dynamically loadable module stuff */
|
||||
#ifdef COMPILE_DL_LIBXML
|
||||
#ifdef ZTS
|
||||
ZEND_TSRMLS_CACHE_DEFINE;
|
||||
ZEND_TSRMLS_CACHE_DEFINE();
|
||||
#endif
|
||||
ZEND_GET_MODULE(libxml)
|
||||
#endif /* COMPILE_DL_LIBXML */
|
||||
@ -272,7 +272,7 @@ static void php_libxml_node_free_list(xmlNodePtr node)
|
||||
static PHP_GINIT_FUNCTION(libxml)
|
||||
{
|
||||
#if defined(COMPILE_DL_LIBXML) && defined(ZTS)
|
||||
ZEND_TSRMLS_CACHE_UPDATE;
|
||||
ZEND_TSRMLS_CACHE_UPDATE();
|
||||
#endif
|
||||
ZVAL_UNDEF(&libxml_globals->stream_context);
|
||||
libxml_globals->error_buffer.s = NULL;
|
||||
@ -752,7 +752,7 @@ PHP_LIBXML_API void php_libxml_shutdown(void)
|
||||
#if defined(LIBXML_SCHEMAS_ENABLED)
|
||||
xmlRelaxNGCleanupTypes();
|
||||
#endif
|
||||
xmlCleanupParser();
|
||||
/* xmlCleanupParser(); */
|
||||
zend_hash_destroy(&php_libxml_exports);
|
||||
|
||||
xmlSetExternalEntityLoader(_php_libxml_default_entity_loader);
|
||||
|
@ -115,7 +115,7 @@ PHP_LIBXML_API void php_libxml_shutdown(void);
|
||||
#ifdef ZTS
|
||||
#define LIBXML(v) ZEND_TSRMG(libxml_globals_id, zend_libxml_globals *, v)
|
||||
#ifdef COMPILE_DL_LIBXML
|
||||
ZEND_TSRMLS_CACHE_EXTERN;
|
||||
ZEND_TSRMLS_CACHE_EXTERN();
|
||||
#endif
|
||||
#else
|
||||
#define LIBXML(v) (libxml_globals.v)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user