1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Merge branch 'master' into issue-67910

Conflicts:
	README.PARAMETER_PARSING_API
	ext/gmp/tests/001.phpt
This commit is contained in:
Florian MARGAINE
2014-09-20 10:09:21 +02:00
1070 changed files with 12427 additions and 11238 deletions

View File

@@ -638,3 +638,28 @@ document zmemcheck
usage: zmemcheck [ptr].
if ptr is 0, all blocks will be listed.
end
define lookup_root
set $found = 0
if gc_globals->roots
set $current = gc_globals->roots->next
printf "looking ref %p in roots\n", $arg0
while $current != &gc_globals->roots
if $current->ref == $arg0
set $found = $current
break
end
set $current = $current->next
end
if $found != 0
printf "found root %p\n", $found
else
printf "not found\n"
end
end
end
document lookup_root
lookup a refcounted in root
usage: lookup_root [ptr].
end

5
NEWS
View File

@@ -10,6 +10,8 @@ PHP NEWS
- Core:
. Added PHP_INT_MIN constant. (Andrea)
. Added Closure::apply() method. (Andrea)
. Implemented FR #38409 (parse_ini_file() looses the type of booleans). (Tjerk)
. Fixed #67959 (Segfault when calling phpversion('spl')). (Florian)
- Reflection
. Fixed inheritance chain of Reflector interface (Tjerk)
@@ -39,4 +41,7 @@ PHP NEWS
. Implemented #67886 (SplPriorityQueue/SplHeap doesn't expose extractFlags
nor curruption state). (Julien)
- DOM:
. Made DOMNode::textContent writeable. (Tjerk)
<<< NOTE: Insert NEWS from last stable release here prior to actual release! >>>

View File

@@ -50,7 +50,7 @@ Type specifiers
instance of that class.
a - array (zval*)
A - array or object (zval *)
A - array or object (zval*)
b - boolean (zend_bool)
C - class (zend_class_entry*)
d - double (double)
@@ -58,15 +58,16 @@ Type specifiers
zend_fcall_info and zend_fcall_info_cache)
h - array (returned as HashTable*)
H - array or HASH_OF(object) (returned as HashTable*)
l - long (long)
L - long, limits out-of-range numbers to LONG_MAX/LONG_MIN (long)
l - long (zend_long)
L - long, limits out-of-range numbers to LONG_MAX/LONG_MIN (zend_long)
o - object of any type (zval*)
O - object of specific type given by class entry (zval*, zend_class_entry)
p - valid path (string without null bytes in the middle) and its length (char*, int)
p - valid path (string without null bytes in the middle) and its length (char*, size_t)
P - valid path (string without null bytes in the middle) as zend_string (zend_string)
r - resource (zval*)
s - string (with possible null bytes) and its length (char*, int)
s - string (with possible null bytes) and its length (char*, size_t)
S - string (with possible null bytes) as zend_string (zend_string)
z - the actual zval (zval*)
Z - the actual zval (zval**)
* - variable arguments list (0 or more)
+ - variable arguments list (1 or more)
@@ -80,28 +81,26 @@ Type specifiers
passed and the output for such type is a pointer, then the output
pointer is set to a native NULL pointer.
For 'b', 'l' and 'd', an extra argument of type zend_bool* must be
passed after the corresponding bool*, long* or double* arguments,
respectively. A non-zero value will be written to the zend_bool iif a
passed after the corresponding bool*, zend_long* or double* arguments,
respectively. A non-zero value will be written to the zend_bool if a
PHP NULL is passed.
Note on 64bit compatibility
---------------------------
Please do not forget that int and long are two different things on 64bit
OSes (int is 4 bytes and long is 8 bytes), so make sure you pass longs to "l"
and ints to strings length (i.e. for "s" you need to pass char * and int),
Please note that since version 7 PHP uses zend_long as integer type and
zend_string with size_t as length, so make sure you pass zend_longs to "l"
and size_t to strings length (i.e. for "s" you need to pass char * and int),
not the other way round!
Remember: "l" is the only case when you need to pass long (and that's why
it's "l", not "i" btw).
Both mistakes cause memory corruptions and segfaults on 64bit OSes:
Both mistakes might cause memory corruptions and segfaults:
1)
char *str;
long str_len; /* XXX THIS IS WRONG!! Use int instead. */
long str_len; /* XXX THIS IS WRONG!! Use size_t instead. */
zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len)
2)
int num; /* XXX THIS IS WRONG!! Use long instead. */
int num; /* XXX THIS IS WRONG!! Use zend_long instead. */
zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &num)
If you're in doubt, use check_parameters.php script to the parameters
@@ -113,9 +112,9 @@ and their types (it can be found in ./scripts/dev/ directory of PHP sources):
Examples
--------
/* Gets a long, a string and its length, and a zval */
long l;
zend_long l;
char *s;
int s_len;
size_t s_len;
zval *param;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lsz",
&l, &s, &s_len, &param) == FAILURE) {
@@ -151,16 +150,16 @@ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/!",
}
/* Get either a set of 3 longs or a string. */
long l1, l2, l3;
zend_long l1, l2, l3;
char *s;
/*
* The function expects a pointer to a integer in this case, not a long
* The function expects a pointer to a size_t in this case, not a long
* or any other type. If you specify a type which is larger
* than a 'int', the upper bits might not be initialized
* than a 'size_t', the upper bits might not be initialized
* properly, leading to random crashes on platforms like
* Tru64 or Linux/Alpha.
*/
int length;
size_t length;
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC,
"lll", &l1, &l2, &l3) == SUCCESS) {
@@ -178,7 +177,7 @@ if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC,
/* Function that accepts only varargs (0 or more) */
int i, num_varargs;
zval ***varargs = NULL;
zval *varargs = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "*", &varargs, &num_varargs) == FAILURE) {
@@ -197,9 +196,9 @@ if (varargs) {
/* Function that accepts a string, followed by varargs (1 or more) */
char *str;
int str_len;
size_t str_len;
int i, num_varargs;
zval ***varargs = NULL;
zval *varargs = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s+", &str, &str_len, &varargs, &num_varargs) == FAILURE) {
return;
@@ -209,16 +208,11 @@ for (i = 0; i < num_varargs; i++) {
/* do something with varargs[i] */
}
if (varargs) {
efree(varargs);
}
/* Function that takes an array, followed by varargs, and ending with a long */
long num;
zend_long num;
zval *array;
int i, num_varargs;
zval ***varargs = NULL;
zval *varargs = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a*l", &array, &varargs, &num_varargs, &num) == FAILURE) {
return;
@@ -227,7 +221,3 @@ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a*l", &array, &varargs, &n
for (i = 0; i < num_varargs; i++) {
/* do something with varargs[i] */
}
if (varargs) {
efree(varargs);
}

View File

@@ -64,7 +64,7 @@ typedef int ts_rsrc_id;
/* Define THREAD_T and MUTEX_T */
#ifdef TSRM_WIN32
# define THREAD_T UINT_PTR
# define THREAD_T DWORD
# define MUTEX_T CRITICAL_SECTION *
#elif defined(GNUPTH)
# define THREAD_T pth_t

View File

@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
| PHP Version 7 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+

View File

@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
| PHP Version 7 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+

View File

@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
| PHP Version 7 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+

View File

@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
| PHP Version 7 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+

View File

@@ -52,6 +52,10 @@ PHP X.Y UPGRADE NOTES
5. Changed Functions
========================================
- parse_ini_file():
- parse_ini_string():
Added scanner mode INI_SCANNER_TYPED to yield typed .ini values.
========================================
6. New Functions

View File

@@ -179,6 +179,10 @@ SOURCE=.\zend_indent.c
# End Source File
# Begin Source File
SOURCE=.\zend_inheritance.c
# End Source File
# Begin Source File
SOURCE=.\zend_ini.c
# End Source File
# Begin Source File

View File

@@ -205,6 +205,10 @@ SOURCE=.\zend_indent.c
# End Source File
# Begin Source File
SOURCE=.\zend_inheritance.c
# End Source File
# Begin Source File
SOURCE=.\zend_ini.c
# End Source File
# Begin Source File

View File

@@ -22,5 +22,5 @@ switch (1) {
}
?>
--EXPECT--
3
--EXPECTF--
Fatal error: Switch statements may only contain one default clause in %s on line 13

16
Zend/tests/bug67985.phpt Normal file
View File

@@ -0,0 +1,16 @@
--TEST--
Bug #67985 - Last used array index not copied to new array at assignment
--FILE--
<?php
$a = ['zero', 'one', 'two'];
unset($a[2]);
$b = $a;
$a[] = 'three';
$b[] = 'three';
var_dump($a === $b);
?>
--EXPECT--
bool(true)

View File

@@ -0,0 +1,24 @@
--TEST--
Stress test $x .= $x
--FILE--
<?php
/*
* Test case for a concat_function() change that broke a test outside of Zend
*
* @see https://github.com/php/php-src/commit/29397f8fd2b4bc8d95e18448ca2d27a62241a407
**/
$result = 'f';
for ($i = 0; $i < 25; ++$i) {
$result .= $result;
}
var_dump(strlen($result));
echo "Done\n";
?>
--EXPECT--
int(33554432)
Done

28
Zend/tests/gc_033.phpt Normal file
View File

@@ -0,0 +1,28 @@
--TEST--
GC 033: Crash in GC while run with phpspec
--FILE--
<?php
$a = new stdClass();
$a->a = array();
$a->a[0] = new Stdclass();
$a->a[0]->a = $a;
$a->a[1] = &$a->a;
/* remove the self-reference array out of roots */
gc_collect_cycles();
/* do unset */
unset($a);
/* let's full the gc roots */
for ($i=0; $i<9999; $i++) {
$b = range(0, 1);
$b[0] = &$b;
unset($b);
}
/* then $a will be freed, but $a->a[0] is not. reference to a freed $a */
var_dump(gc_collect_cycles());
?>
--EXPECT--
int(20001)

View File

@@ -62,14 +62,14 @@ ZEND_API char *(*zend_resolve_path)(const char *filename, int filename_len TSRML
void (*zend_on_timeout)(int seconds TSRMLS_DC);
static void (*zend_message_dispatcher_p)(zend_long message, const void *data TSRMLS_DC);
static int (*zend_get_configuration_directive_p)(const char *name, uint name_length, zval *contents);
static zval *(*zend_get_configuration_directive_p)(zend_string *name);
static ZEND_INI_MH(OnUpdateErrorReporting) /* {{{ */
{
if (!new_value) {
EG(error_reporting) = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED;
} else {
EG(error_reporting) = atoi(new_value);
EG(error_reporting) = atoi(new_value->val);
}
return SUCCESS;
}
@@ -77,7 +77,7 @@ static ZEND_INI_MH(OnUpdateErrorReporting) /* {{{ */
static ZEND_INI_MH(OnUpdateGCEnabled) /* {{{ */
{
OnUpdateBool(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
OnUpdateBool(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
if (GC_G(gc_enabled)) {
gc_init(TSRMLS_C);
@@ -95,7 +95,7 @@ static ZEND_INI_MH(OnUpdateScriptEncoding) /* {{{ */
if (!zend_multibyte_get_functions(TSRMLS_C)) {
return SUCCESS;
}
return zend_multibyte_set_script_encoding_by_string(new_value, new_value_length TSRMLS_CC);
return zend_multibyte_set_script_encoding_by_string(new_value->val, new_value->len TSRMLS_CC);
}
/* }}} */
@@ -156,8 +156,8 @@ static void print_hash(zend_write_func_t write_func, HashTable *ht, int indent,
if (string_key) {
if (is_object) {
const char *prop_name, *class_name;
int prop_len;
int mangled = zend_unmangle_property_name_ex(string_key->val, string_key->len, &class_name, &prop_name, &prop_len);
size_t prop_len;
int mangled = zend_unmangle_property_name_ex(string_key, &class_name, &prop_name, &prop_len);
ZEND_WRITE_EX(prop_name, prop_len);
if (class_name && mangled == SUCCESS) {
@@ -278,7 +278,7 @@ again:
case IS_REFERENCE:
expr = Z_REFVAL_P(expr);
if (Z_TYPE_P(expr) == IS_STRING) {
ZVAL_STR(expr_copy, zend_string_copy(Z_STR_P(expr)));
ZVAL_STR_COPY(expr_copy, Z_STR_P(expr));
return 1;
}
goto again;
@@ -509,11 +509,20 @@ static void compiler_globals_ctor(zend_compiler_globals *compiler_globals TSRMLS
compiler_globals->last_static_member = zend_hash_num_elements(compiler_globals->class_table);
if (compiler_globals->last_static_member) {
compiler_globals->static_members_table = calloc(compiler_globals->last_static_member, sizeof(zval**));
compiler_globals->static_members_table = calloc(compiler_globals->last_static_member, sizeof(zval*));
} else {
compiler_globals->static_members_table = NULL;
}
compiler_globals->script_encoding_list = NULL;
#ifdef ZTS
compiler_globals->empty_string = zend_string_alloc(sizeof("")-1, 1);
compiler_globals->empty_string->val[0] = '\000';
zend_string_hash_val(compiler_globals->empty_string);
compiler_globals->empty_string->gc.u.v.flags |= IS_STR_INTERNED;
memset(compiler_globals->one_char_string, 0, sizeof(compiler_globals->one_char_string));
#endif
}
/* }}} */
@@ -538,6 +547,10 @@ static void compiler_globals_dtor(zend_compiler_globals *compiler_globals TSRMLS
pefree((char*)compiler_globals->script_encoding_list, 1);
}
compiler_globals->last_static_member = 0;
#ifdef ZTS
zend_string_release(compiler_globals->empty_string);
#endif
}
/* }}} */
@@ -812,10 +825,35 @@ void zend_shutdown(TSRMLS_D) /* {{{ */
zend_shutdown_timeout_thread();
#endif
zend_destroy_rsrc_list(&EG(persistent_list) TSRMLS_CC);
if (EG(active))
{
/*
* The order of destruction is important here.
* See bugs #65463 and 66036.
*/
zend_function *func;
zend_class_entry *ce;
ZEND_HASH_REVERSE_FOREACH_PTR(GLOBAL_FUNCTION_TABLE, func) {
if (func->type == ZEND_USER_FUNCTION) {
zend_cleanup_op_array_data((zend_op_array *) func);
}
} ZEND_HASH_FOREACH_END();
ZEND_HASH_REVERSE_FOREACH_PTR(GLOBAL_CLASS_TABLE, ce) {
if (ce->type == ZEND_USER_CLASS) {
zend_cleanup_user_class_data(ce TSRMLS_CC);
} else {
break;
}
} ZEND_HASH_FOREACH_END();
zend_cleanup_internal_classes(TSRMLS_C);
zend_hash_reverse_apply(GLOBAL_FUNCTION_TABLE, (apply_func_t) clean_non_persistent_function_full TSRMLS_CC);
zend_hash_reverse_apply(GLOBAL_CLASS_TABLE, (apply_func_t) clean_non_persistent_class_full TSRMLS_CC);
}
zend_destroy_modules();
virtual_cwd_deactivate(TSRMLS_C);
virtual_cwd_shutdown();
virtual_cwd_deactivate(TSRMLS_C);
virtual_cwd_shutdown();
zend_hash_destroy(GLOBAL_FUNCTION_TABLE);
zend_hash_destroy(GLOBAL_CLASS_TABLE);
@@ -979,12 +1017,12 @@ ZEND_API void zend_message_dispatcher(zend_long message, const void *data TSRMLS
/* }}} */
END_EXTERN_C()
ZEND_API int zend_get_configuration_directive(const char *name, uint name_length, zval *contents) /* {{{ */
ZEND_API zval *zend_get_configuration_directive(zend_string *name) /* {{{ */
{
if (zend_get_configuration_directive_p) {
return zend_get_configuration_directive_p(name, name_length, contents);
return zend_get_configuration_directive_p(name);
} else {
return FAILURE;
return NULL;
}
}
/* }}} */
@@ -1006,11 +1044,17 @@ ZEND_API int zend_get_configuration_directive(const char *name, uint name_length
} \
} while (0)
#if !defined(ZEND_WIN32) && !defined(DARWIN)
ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
#else
static void zend_error_va_list(int type, const char *format, va_list args)
#endif
{
char *str;
int len;
#if !defined(ZEND_WIN32) && !defined(DARWIN)
va_list args;
#endif
va_list usr_copy;
zval params[5];
zval retval;
@@ -1113,7 +1157,9 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
}
#endif /* HAVE_DTRACE */
#if !defined(ZEND_WIN32) && !defined(DARWIN)
va_start(args, format);
#endif
/* if we don't have a user defined error handler */
if (Z_TYPE(EG(user_error_handler)) == IS_UNDEF
@@ -1224,7 +1270,9 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
break;
}
#if !defined(ZEND_WIN32) && !defined(DARWIN)
va_end(args);
#endif
if (type == E_PARSE) {
/* eval() errors do not affect exit_status */
@@ -1239,8 +1287,27 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
}
/* }}} */
#if defined(__GNUC__) && __GNUC__ >= 3 && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) && !defined(__osf__)
#if (defined(__GNUC__) && __GNUC__ >= 3 && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) && !defined(__osf__))
void zend_error_noreturn(int type, const char *format, ...) __attribute__ ((alias("zend_error"),noreturn));
#elif defined(ZEND_WIN32) || defined(DARWIN)
ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
{
va_list va;
va_start(va, format);
zend_error_va_list(type, format, va);
va_end(va);
}
ZEND_API ZEND_NORETURN void zend_error_noreturn(int type, const char *format, ...)
{
va_list va;
va_start(va, format);
zend_error_va_list(type, format, va);
va_end(va);
}
/* }}} */
#endif
ZEND_API void zend_output_debug_string(zend_bool trigger_break, const char *format, ...) /* {{{ */
@@ -1357,6 +1424,7 @@ void free_estring(char **str_p) /* {{{ */
{
efree(*str_p);
}
/* }}} */
void free_string_zval(zval *zv) /* {{{ */
{

View File

@@ -26,272 +26,31 @@
#define ZEND_ENGINE_2
#ifdef __cplusplus
#define BEGIN_EXTERN_C() extern "C" {
#define END_EXTERN_C() }
#else
#define BEGIN_EXTERN_C()
#define END_EXTERN_C()
#endif
/*
* general definitions
*/
#ifdef ZEND_WIN32
# include "zend_config.w32.h"
# define ZEND_PATHS_SEPARATOR ';'
#elif defined(NETWARE)
# include <zend_config.h>
# define ZEND_PATHS_SEPARATOR ';'
#elif defined(__riscos__)
# include <zend_config.h>
# define ZEND_PATHS_SEPARATOR ';'
#else
# include <zend_config.h>
# define ZEND_PATHS_SEPARATOR ':'
#endif
/* Only use this macro if you know for sure that all of the switches values
are covered by its case statements */
#if ZEND_DEBUG
# define EMPTY_SWITCH_DEFAULT_CASE() default: ZEND_ASSERT(0); break;
#elif defined(ZEND_WIN32)
# define EMPTY_SWITCH_DEFAULT_CASE() default: __assume(0); break;
#else
# define EMPTY_SWITCH_DEFAULT_CASE()
#endif
/* all HAVE_XXX test have to be after the include of zend_config above */
#include <stdio.h>
#include <assert.h>
#ifdef HAVE_UNIX_H
# include <unix.h>
#endif
#ifdef HAVE_STDARG_H
# include <stdarg.h>
#endif
#ifdef HAVE_DLFCN_H
# include <dlfcn.h>
#endif
#if defined(HAVE_LIBDL) && !defined(ZEND_WIN32)
# ifndef RTLD_LAZY
# define RTLD_LAZY 1 /* Solaris 1, FreeBSD's (2.1.7.1 and older) */
# endif
# ifndef RTLD_GLOBAL
# define RTLD_GLOBAL 0
# endif
# if defined(RTLD_GROUP) && defined(RTLD_WORLD) && defined(RTLD_PARENT)
# define DL_LOAD(libname) dlopen(libname, RTLD_LAZY | RTLD_GLOBAL | RTLD_GROUP | RTLD_WORLD | RTLD_PARENT)
# elif defined(RTLD_DEEPBIND)
# define DL_LOAD(libname) dlopen(libname, RTLD_LAZY | RTLD_GLOBAL | RTLD_DEEPBIND)
# else
# define DL_LOAD(libname) dlopen(libname, RTLD_LAZY | RTLD_GLOBAL)
# endif
# define DL_UNLOAD dlclose
# if defined(DLSYM_NEEDS_UNDERSCORE)
# define DL_FETCH_SYMBOL(h,s) dlsym((h), "_" s)
# else
# define DL_FETCH_SYMBOL dlsym
# endif
# define DL_ERROR dlerror
# define DL_HANDLE void *
# define ZEND_EXTENSIONS_SUPPORT 1
#elif defined(ZEND_WIN32)
# define DL_LOAD(libname) LoadLibrary(libname)
# define DL_FETCH_SYMBOL GetProcAddress
# define DL_UNLOAD FreeLibrary
# define DL_HANDLE HMODULE
# define ZEND_EXTENSIONS_SUPPORT 1
#else
# define DL_HANDLE void *
# define ZEND_EXTENSIONS_SUPPORT 0
#endif
#if HAVE_ALLOCA_H && !defined(_ALLOCA_H)
# include <alloca.h>
#endif
/* AIX requires this to be the first thing in the file. */
#ifndef __GNUC__
# ifndef HAVE_ALLOCA_H
# ifdef _AIX
#pragma alloca
# else
# ifndef alloca /* predefined by HP cc +Olibcalls */
char *alloca ();
# endif
# endif
# endif
#endif
/* Compatibility with non-clang compilers */
#ifndef __has_attribute
# define __has_attribute(x) 0
#endif
/* GCC x.y.z supplies __GNUC__ = x and __GNUC_MINOR__ = y */
#ifdef __GNUC__
# define ZEND_GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
#else
# define ZEND_GCC_VERSION 0
#endif
#if ZEND_GCC_VERSION >= 2096
# define ZEND_ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
#else
# define ZEND_ATTRIBUTE_MALLOC
#endif
#if ZEND_GCC_VERSION >= 4003 || __has_attribute(alloc_size)
# define ZEND_ATTRIBUTE_ALLOC_SIZE(X) __attribute__ ((alloc_size(X)))
# define ZEND_ATTRIBUTE_ALLOC_SIZE2(X,Y) __attribute__ ((alloc_size(X,Y)))
#else
# define ZEND_ATTRIBUTE_ALLOC_SIZE(X)
# define ZEND_ATTRIBUTE_ALLOC_SIZE2(X,Y)
#endif
#if ZEND_GCC_VERSION >= 2007
# define ZEND_ATTRIBUTE_FORMAT(type, idx, first) __attribute__ ((format(type, idx, first)))
#else
# define ZEND_ATTRIBUTE_FORMAT(type, idx, first)
#endif
#if ZEND_GCC_VERSION >= 3001 && !defined(__INTEL_COMPILER)
# define ZEND_ATTRIBUTE_PTR_FORMAT(type, idx, first) __attribute__ ((format(type, idx, first)))
#else
# define ZEND_ATTRIBUTE_PTR_FORMAT(type, idx, first)
#endif
#if ZEND_GCC_VERSION >= 3001
# define ZEND_ATTRIBUTE_DEPRECATED __attribute__((deprecated))
#elif defined(ZEND_WIN32) && defined(_MSC_VER) && _MSC_VER >= 1300
# define ZEND_ATTRIBUTE_DEPRECATED __declspec(deprecated)
#else
# define ZEND_ATTRIBUTE_DEPRECATED
#endif
#if defined(__GNUC__) && ZEND_GCC_VERSION >= 4003
# define ZEND_ATTRIBUTE_UNUSED __attribute__((unused))
# define ZEND_ATTRIBUTE_UNUSED_LABEL __attribute__((cold, unused));
#else
# define ZEND_ATTRIBUTE_UNUSED
# define ZEND_ATTRIBUTE_UNUSED_LABEL
#endif
#if defined(__GNUC__) && ZEND_GCC_VERSION >= 3004 && defined(__i386__)
# define ZEND_FASTCALL __attribute__((fastcall))
#elif defined(_MSC_VER) && defined(_M_IX86)
# define ZEND_FASTCALL __fastcall
#else
# define ZEND_FASTCALL
#endif
#if defined(__GNUC__) && ZEND_GCC_VERSION >= 3004
#else
# define __restrict__
#endif
#define restrict __restrict__
#if (HAVE_ALLOCA || (defined (__GNUC__) && __GNUC__ >= 2)) && !(defined(ZTS) && defined(NETWARE)) && !(defined(ZTS) && defined(HPUX)) && !defined(DARWIN)
# define ZEND_ALLOCA_MAX_SIZE (32 * 1024)
# define ALLOCA_FLAG(name) \
zend_bool name;
# define SET_ALLOCA_FLAG(name) \
name = 1
# define do_alloca_ex(size, limit, use_heap) \
((use_heap = (UNEXPECTED((size) > (limit)))) ? emalloc(size) : alloca(size))
# define do_alloca(size, use_heap) \
do_alloca_ex(size, ZEND_ALLOCA_MAX_SIZE, use_heap)
# define free_alloca(p, use_heap) \
do { if (UNEXPECTED(use_heap)) efree(p); } while (0)
#else
# define ALLOCA_FLAG(name)
# define SET_ALLOCA_FLAG(name)
# define do_alloca(p, use_heap) emalloc(p)
# define free_alloca(p, use_heap) efree(p)
#endif
#if ZEND_DEBUG
#define ZEND_FILE_LINE_D const char *__zend_filename, const uint __zend_lineno
#define ZEND_FILE_LINE_DC , ZEND_FILE_LINE_D
#define ZEND_FILE_LINE_ORIG_D const char *__zend_orig_filename, const uint __zend_orig_lineno
#define ZEND_FILE_LINE_ORIG_DC , ZEND_FILE_LINE_ORIG_D
#define ZEND_FILE_LINE_RELAY_C __zend_filename, __zend_lineno
#define ZEND_FILE_LINE_RELAY_CC , ZEND_FILE_LINE_RELAY_C
#define ZEND_FILE_LINE_C __FILE__, __LINE__
#define ZEND_FILE_LINE_CC , ZEND_FILE_LINE_C
#define ZEND_FILE_LINE_EMPTY_C NULL, 0
#define ZEND_FILE_LINE_EMPTY_CC , ZEND_FILE_LINE_EMPTY_C
#define ZEND_FILE_LINE_ORIG_RELAY_C __zend_orig_filename, __zend_orig_lineno
#define ZEND_FILE_LINE_ORIG_RELAY_CC , ZEND_FILE_LINE_ORIG_RELAY_C
#define ZEND_ASSERT(c) assert(c)
#else
#define ZEND_FILE_LINE_D
#define ZEND_FILE_LINE_DC
#define ZEND_FILE_LINE_ORIG_D
#define ZEND_FILE_LINE_ORIG_DC
#define ZEND_FILE_LINE_RELAY_C
#define ZEND_FILE_LINE_RELAY_CC
#define ZEND_FILE_LINE_C
#define ZEND_FILE_LINE_CC
#define ZEND_FILE_LINE_EMPTY_C
#define ZEND_FILE_LINE_EMPTY_CC
#define ZEND_FILE_LINE_ORIG_RELAY_C
#define ZEND_FILE_LINE_ORIG_RELAY_CC
#define ZEND_ASSERT(c)
#endif /* ZEND_DEBUG */
#ifdef ZTS
#define ZTS_V 1
#else
#define ZTS_V 0
#endif
#include "zend_errors.h"
#include "zend_alloc.h"
#define ZEND_MAX_RESERVED_RESOURCES 4
#include "zend_types.h"
#ifdef HAVE_LIMITS_H
# include <limits.h>
#endif
#ifndef LONG_MAX
#define LONG_MAX 2147483647L
#endif
#ifndef LONG_MIN
#define LONG_MIN (- LONG_MAX - 1)
#endif
#if SIZEOF_ZEND_LONG == 4
#define MAX_LENGTH_OF_LONG 11
static const char long_min_digits[] = "2147483648";
#elif SIZEOF_ZEND_LONG == 8
#define MAX_LENGTH_OF_LONG 20
static const char long_min_digits[] = "9223372036854775808";
#else
#error "Unknown SIZEOF_ZEND_LONG"
#endif
#define MAX_LENGTH_OF_DOUBLE 32
typedef enum {
SUCCESS = 0,
FAILURE = -1, /* this MUST stay a negative number, or it may affect functions! */
} ZEND_RESULT_CODE;
#include "zend_errors.h"
#include "zend_alloc.h"
#include "zend_hash.h"
#include "zend_llist.h"
#include "zend_string.h"
#include "zend_ast.h"
#include "zend_gc.h"
#include "zend_variables.h"
#include "zend_iterators.h"
#include "zend_stream.h"
#ifdef ZEND_SIGNALS
# include "zend_signal.h"
#endif
#ifndef ZEND_SIGNALS
# define HANDLE_BLOCK_INTERRUPTIONS() if (zend_block_interruptions) { zend_block_interruptions(); }
# define HANDLE_UNBLOCK_INTERRUPTIONS() if (zend_unblock_interruptions) { zend_unblock_interruptions(); }
#else
# define HANDLE_BLOCK_INTERRUPTIONS() ZEND_SIGNAL_BLOCK_INTERRUPUTIONS()
# define HANDLE_UNBLOCK_INTERRUPTIONS() ZEND_SIGNAL_UNBLOCK_INTERRUPTIONS()
#endif
#define INTERNAL_FUNCTION_PARAMETERS uint32_t param_count, zval *return_value TSRMLS_DC
#define INTERNAL_FUNCTION_PARAM_PASSTHRU param_count, return_value TSRMLS_CC
@@ -302,159 +61,42 @@ typedef enum {
!ZEND_USER_CODE(EG(current_execute_data)->prev_execute_data->func->common.type) || \
!(EG(current_execute_data)->prev_execute_data->opline->result_type & EXT_TYPE_UNUSED))
#if defined(__GNUC__) && __GNUC__ >= 3 && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) && !defined(__osf__)
# define ZEND_NORETURN __attribute__((noreturn))
void zend_error_noreturn(int type, const char *format, ...) __attribute__ ((noreturn));
#ifdef HAVE_NORETURN
# if defined(ZEND_WIN32)
ZEND_API ZEND_NORETURN void zend_error_noreturn(int type, const char *format, ...);
# else
void zend_error_noreturn(int type, const char *format, ...) ZEND_NORETURN;
# endif
#else
# define ZEND_NORETURN
# define zend_error_noreturn zend_error
# define zend_error_noreturn zend_error
#endif
#include "zend_object_handlers.h"
/* overloaded elements data types */
#define OE_IS_ARRAY (1<<0)
#define OE_IS_OBJECT (1<<1)
#define OE_IS_METHOD (1<<2)
#define Z_REFCOUNT_P(pz) zval_refcount_p(pz)
#define Z_SET_REFCOUNT_P(pz, rc) zval_set_refcount_p(pz, rc)
#define Z_ADDREF_P(pz) zval_addref_p(pz)
#define Z_DELREF_P(pz) zval_delref_p(pz)
#define Z_REFCOUNT(z) Z_REFCOUNT_P(&(z))
#define Z_SET_REFCOUNT(z, rc) Z_SET_REFCOUNT_P(&(z), rc)
#define Z_ADDREF(z) Z_ADDREF_P(&(z))
#define Z_DELREF(z) Z_DELREF_P(&(z))
#define Z_TRY_ADDREF_P(pz) do { \
if (Z_REFCOUNTED_P((pz))) { \
Z_ADDREF_P((pz)); \
} \
} while (0)
#define Z_TRY_DELREF_P(pz) do { \
if (Z_REFCOUNTED_P((pz))) { \
Z_DELREF_P((pz)); \
} \
} while (0)
#define Z_TRY_ADDREF(z) Z_TRY_ADDREF_P(&(z))
#define Z_TRY_DELREF(z) Z_TRY_DELREF_P(&(z))
#if ZEND_DEBUG
#define zend_always_inline inline
#define zend_never_inline
#else
#if defined(__GNUC__)
#if __GNUC__ >= 3
#define zend_always_inline inline __attribute__((always_inline))
#define zend_never_inline __attribute__((noinline))
#else
#define zend_always_inline inline
#define zend_never_inline
#endif
#elif defined(_MSC_VER)
#define zend_always_inline __forceinline
#define zend_never_inline
#else
#define zend_always_inline inline
#define zend_never_inline
#endif
#endif /* ZEND_DEBUG */
#if (defined (__GNUC__) && __GNUC__ > 2 ) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX)
# define EXPECTED(condition) __builtin_expect(!(!(condition)), 1)
# define UNEXPECTED(condition) __builtin_expect(!(!(condition)), 0)
#else
# define EXPECTED(condition) (condition)
# define UNEXPECTED(condition) (condition)
#endif
#ifndef XtOffsetOf
# if defined(CRAY) || (defined(__ARMCC_VERSION) && !defined(LINUX))
# ifdef __STDC__
# define XtOffset(p_type, field) _Offsetof(p_type, field)
# else
# ifdef CRAY2
# define XtOffset(p_type, field) \
(sizeof(int)*((unsigned int)&(((p_type)NULL)->field)))
# else /* !CRAY2 */
# define XtOffset(p_type, field) ((unsigned int)&(((p_type)NULL)->field))
# endif /* !CRAY2 */
# endif /* __STDC__ */
# else /* ! (CRAY || __arm) */
# define XtOffset(p_type, field) \
((zend_long) (((char *) (&(((p_type)NULL)->field))) - ((char *) NULL)))
# endif /* !CRAY */
# ifdef offsetof
# define XtOffsetOf(s_type, field) offsetof(s_type, field)
# else
# define XtOffsetOf(s_type, field) XtOffset(s_type*, field)
# endif
#endif
#include "zend_string.h"
#include "zend_ast.h"
static zend_always_inline uint32_t zval_refcount_p(zval* pz) {
ZEND_ASSERT(Z_REFCOUNTED_P(pz) || Z_IMMUTABLE_P(pz));
return GC_REFCOUNT(Z_COUNTED_P(pz));
}
static zend_always_inline uint32_t zval_set_refcount_p(zval* pz, uint32_t rc) {
ZEND_ASSERT(Z_REFCOUNTED_P(pz));
return GC_REFCOUNT(Z_COUNTED_P(pz)) = rc;
}
static zend_always_inline uint32_t zval_addref_p(zval* pz) {
ZEND_ASSERT(Z_REFCOUNTED_P(pz));
return ++GC_REFCOUNT(Z_COUNTED_P(pz));
}
static zend_always_inline uint32_t zval_delref_p(zval* pz) {
ZEND_ASSERT(Z_REFCOUNTED_P(pz));
return --GC_REFCOUNT(Z_COUNTED_P(pz));
}
/* excpt.h on Digital Unix 4.0 defines function_table */
#undef function_table
/* A lot of stuff needs shifiting around in order to include zend_compile.h here */
union _zend_function;
#include "zend_iterators.h"
struct _zend_serialize_data;
struct _zend_unserialize_data;
typedef struct _zend_serialize_data zend_serialize_data;
typedef struct _zend_unserialize_data zend_unserialize_data;
struct _zend_trait_method_reference {
typedef struct _zend_trait_method_reference {
zend_string *method_name;
zend_class_entry *ce;
zend_string *class_name;
};
typedef struct _zend_trait_method_reference zend_trait_method_reference;
} zend_trait_method_reference;
struct _zend_trait_precedence {
typedef struct _zend_trait_precedence {
zend_trait_method_reference *trait_method;
union {
zend_class_entry *ce;
zend_string *class_name;
} *exclude_from_classes;
};
typedef struct _zend_trait_precedence zend_trait_precedence;
} zend_trait_precedence;
struct _zend_trait_alias {
typedef struct _zend_trait_alias {
zend_trait_method_reference *trait_method;
/**
@@ -466,8 +108,7 @@ struct _zend_trait_alias {
* modifiers to be set on trait method
*/
uint32_t modifiers;
};
typedef struct _zend_trait_alias zend_trait_alias;
} zend_trait_alias;
struct _zend_class_entry {
char type;
@@ -508,8 +149,8 @@ struct _zend_class_entry {
union _zend_function *(*get_static_method)(zend_class_entry *ce, zend_string* method TSRMLS_DC);
/* serializer callbacks */
int (*serialize)(zval *object, unsigned char **buffer, uint32_t *buf_len, zend_serialize_data *data TSRMLS_DC);
int (*unserialize)(zval *object, zend_class_entry *ce, const unsigned char *buf, uint32_t buf_len, zend_unserialize_data *data TSRMLS_DC);
int (*serialize)(zval *object, unsigned char **buffer, size_t *buf_len, zend_serialize_data *data TSRMLS_DC);
int (*unserialize)(zval *object, zend_class_entry *ce, const unsigned char *buf, size_t buf_len, zend_unserialize_data *data TSRMLS_DC);
uint32_t num_interfaces;
uint32_t num_traits;
@@ -533,7 +174,6 @@ struct _zend_class_entry {
} info;
};
#include "zend_stream.h"
typedef struct _zend_utility_functions {
void (*error_function)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 4, 0);
size_t (*printf_function)(const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 1, 2);
@@ -542,7 +182,7 @@ typedef struct _zend_utility_functions {
void (*message_handler)(zend_long message, const void *data TSRMLS_DC);
void (*block_interruptions)(void);
void (*unblock_interruptions)(void);
int (*get_configuration_directive)(const char *name, uint name_length, zval *contents);
zval *(*get_configuration_directive)(zend_string *name);
void (*ticks_function)(int ticks TSRMLS_DC);
void (*on_timeout)(int seconds TSRMLS_DC);
int (*stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC);
@@ -560,39 +200,8 @@ typedef struct _zend_utility_values {
typedef int (*zend_write_func_t)(const char *str, uint str_length);
#undef MIN
#undef MAX
#define MAX(a, b) (((a)>(b))?(a):(b))
#define MIN(a, b) (((a)<(b))?(a):(b))
#define ZEND_STRL(str) (str), (sizeof(str)-1)
#define ZEND_STRS(str) (str), (sizeof(str))
#define ZEND_NORMALIZE_BOOL(n) \
((n) ? (((n)>0) ? 1 : -1) : 0)
#define ZEND_TRUTH(x) ((x) ? 1 : 0)
#define ZEND_LOG_XOR(a, b) (ZEND_TRUTH(a) ^ ZEND_TRUTH(b))
int zend_startup(zend_utility_functions *utility_functions, char **extensions TSRMLS_DC);
void zend_shutdown(TSRMLS_D);
void zend_register_standard_ini_entries(TSRMLS_D);
void zend_post_startup(TSRMLS_D);
void zend_set_utility_values(zend_utility_values *utility_values);
BEGIN_EXTERN_C()
ZEND_API void _zend_bailout(char *filename, uint lineno);
END_EXTERN_C()
#define zend_bailout() _zend_bailout(__FILE__, __LINE__)
#ifdef HAVE_SIGSETJMP
# define SETJMP(a) sigsetjmp(a, 0)
# define LONGJMP(a,b) siglongjmp(a, b)
# define JMP_BUF sigjmp_buf
#else
# define SETJMP(a) setjmp(a)
# define LONGJMP(a,b) longjmp(a, b)
# define JMP_BUF jmp_buf
#endif
#define zend_try \
{ \
JMP_BUF *__orig_bailout = EG(bailout); \
@@ -610,6 +219,14 @@ END_EXTERN_C()
#define zend_first_try EG(bailout)=NULL; zend_try
BEGIN_EXTERN_C()
int zend_startup(zend_utility_functions *utility_functions, char **extensions TSRMLS_DC);
void zend_shutdown(TSRMLS_D);
void zend_register_standard_ini_entries(TSRMLS_D);
void zend_post_startup(TSRMLS_D);
void zend_set_utility_values(zend_utility_values *utility_values);
ZEND_API void _zend_bailout(char *filename, uint lineno);
ZEND_API char *get_zend_version(void);
ZEND_API int zend_make_printable_zval(zval *expr, zval *expr_copy TSRMLS_DC);
ZEND_API int zend_print_zval(zval *expr, int indent TSRMLS_DC);
@@ -618,24 +235,14 @@ ZEND_API void zend_print_zval_r(zval *expr, int indent TSRMLS_DC);
ZEND_API void zend_print_flat_zval_r(zval *expr TSRMLS_DC);
ZEND_API void zend_print_zval_r_ex(zend_write_func_t write_func, zval *expr, int indent TSRMLS_DC);
ZEND_API void zend_output_debug_string(zend_bool trigger_break, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
END_EXTERN_C()
BEGIN_EXTERN_C()
ZEND_API void zend_activate(TSRMLS_D);
ZEND_API void zend_deactivate(TSRMLS_D);
ZEND_API void zend_call_destructors(TSRMLS_D);
ZEND_API void zend_activate_modules(TSRMLS_D);
ZEND_API void zend_deactivate_modules(TSRMLS_D);
ZEND_API void zend_post_deactivate_modules(TSRMLS_D);
END_EXTERN_C()
#if ZEND_DEBUG
#define Z_DBG(expr) (expr)
#else
#define Z_DBG(expr)
#endif
BEGIN_EXTERN_C()
ZEND_API void free_estring(char **str_p);
ZEND_API void free_string_zval(zval *zv);
END_EXTERN_C()
@@ -676,20 +283,10 @@ END_EXTERN_C()
#define ZEND_UV(name) (zend_uv.name)
#ifndef ZEND_SIGNALS
#define HANDLE_BLOCK_INTERRUPTIONS() if (zend_block_interruptions) { zend_block_interruptions(); }
#define HANDLE_UNBLOCK_INTERRUPTIONS() if (zend_unblock_interruptions) { zend_unblock_interruptions(); }
#else
#include "zend_signal.h"
#define HANDLE_BLOCK_INTERRUPTIONS() ZEND_SIGNAL_BLOCK_INTERRUPUTIONS()
#define HANDLE_UNBLOCK_INTERRUPTIONS() ZEND_SIGNAL_UNBLOCK_INTERRUPTIONS()
#endif
BEGIN_EXTERN_C()
ZEND_API void zend_message_dispatcher(zend_long message, const void *data TSRMLS_DC);
ZEND_API int zend_get_configuration_directive(const char *name, uint name_length, zval *contents);
ZEND_API zval *zend_get_configuration_directive(zend_string *name);
END_EXTERN_C()
/* Messages for applications of Zend */
@@ -701,131 +298,6 @@ END_EXTERN_C()
#define ZMSG_LOG_SCRIPT_NAME 6L
#define ZMSG_MEMORY_LEAKS_GRAND_TOTAL 7L
#define ZVAL_COPY_VALUE(z, v) \
do { \
zval *_z1 = (z); \
zval *_z2 = (v); \
(_z1)->value = (_z2)->value; \
Z_TYPE_INFO_P(_z1) = Z_TYPE_INFO_P(_z2); \
} while (0)
#define ZVAL_COPY(z, v) \
do { \
zval *__z1 = (z); \
zval *__z2 = (v); \
ZVAL_COPY_VALUE(__z1, __z2); \
if (Z_OPT_REFCOUNTED_P(__z1)) { \
Z_ADDREF_P(__z1); \
} \
} while (0)
#define ZVAL_DUP(z, v) \
do { \
zval *__z1 = (z); \
zval *__z2 = (v); \
ZVAL_COPY_VALUE(__z1, __z2); \
zval_opt_copy_ctor(__z1); \
} while (0)
#define ZVAL_DEREF(z) do { \
if (UNEXPECTED(Z_ISREF_P(z))) { \
(z) = Z_REFVAL_P(z); \
} \
} while (0)
#define ZVAL_MAKE_REF(zv) do { \
zval *__zv = (zv); \
if (!Z_ISREF_P(__zv)) { \
ZVAL_NEW_REF(__zv, __zv); \
} \
} while (0)
#define ZVAL_UNREF(z) do { \
zval *_z = (z); \
zend_reference *ref; \
ZEND_ASSERT(Z_ISREF_P(_z)); \
ref = Z_REF_P(_z); \
ZVAL_COPY_VALUE(_z, &ref->val); \
efree_size(ref, sizeof(zend_reference)); \
} while (0)
#define SEPARATE_STRING(zv) do { \
zval *_zv = (zv); \
if (Z_REFCOUNTED_P(_zv) && \
Z_REFCOUNT_P(_zv) > 1) { \
Z_DELREF_P(_zv); \
zval_copy_ctor_func(_zv); \
} \
} while (0)
#define SEPARATE_ARRAY(zv) do { \
zval *_zv = (zv); \
if (Z_REFCOUNT_P(_zv) > 1) { \
if (!Z_IMMUTABLE_P(_zv)) { \
Z_DELREF_P(_zv); \
} \
zval_copy_ctor_func(_zv); \
} \
} while (0)
#define SEPARATE_ZVAL_NOREF(zv) do { \
zval *_zv = (zv); \
if (Z_COPYABLE_P(_zv) || \
Z_IMMUTABLE_P(_zv)) { \
if (Z_REFCOUNT_P(_zv) > 1) { \
if (!Z_IMMUTABLE_P(_zv)) { \
Z_DELREF_P(_zv); \
} \
zval_copy_ctor_func(_zv); \
} \
} \
} while (0)
#define SEPARATE_ZVAL(zv) do { \
zval *_zv = (zv); \
if (Z_REFCOUNTED_P(_zv) || \
Z_IMMUTABLE_P(_zv)) { \
if (Z_REFCOUNT_P(_zv) > 1) { \
if (Z_COPYABLE_P(_zv) || \
Z_IMMUTABLE_P(_zv)) { \
if (!Z_IMMUTABLE_P(_zv)) { \
Z_DELREF_P(_zv); \
} \
zval_copy_ctor_func(_zv); \
} else if (Z_ISREF_P(_zv)) { \
Z_DELREF_P(_zv); \
ZVAL_DUP(_zv, Z_REFVAL_P(_zv)); \
} \
} \
} \
} while (0)
#define SEPARATE_ZVAL_IF_NOT_REF(zv) do { \
zval *_zv = (zv); \
if (Z_COPYABLE_P(_zv) || \
Z_IMMUTABLE_P(_zv)) { \
if (Z_REFCOUNT_P(_zv) > 1) { \
if (!Z_IMMUTABLE_P(_zv)) { \
Z_DELREF_P(_zv); \
} \
zval_copy_ctor_func(_zv); \
} \
} \
} while (0)
#define SEPARATE_ARG_IF_REF(varptr) do { \
ZVAL_DEREF(varptr); \
if (Z_REFCOUNTED_P(varptr)) { \
Z_ADDREF_P(varptr); \
} \
} while (0)
#define ZEND_MAX_RESERVED_RESOURCES 4
#include "zend_gc.h"
#include "zend_operators.h"
#include "zend_variables.h"
typedef enum {
EH_NORMAL = 0,
EH_SUPPRESS,
@@ -845,6 +317,9 @@ ZEND_API void zend_restore_error_handling(zend_error_handling *saved TSRMLS_DC);
#define DEBUG_BACKTRACE_PROVIDE_OBJECT (1<<0)
#define DEBUG_BACKTRACE_IGNORE_ARGS (1<<1)
#include "zend_object_handlers.h"
#include "zend_operators.h"
#endif /* ZEND_H */
/*

View File

@@ -27,6 +27,7 @@
#include "zend_constants.h"
#include "zend_exceptions.h"
#include "zend_closures.h"
#include "zend_inheritance.h"
#ifdef HAVE_STDARG_H
#include <stdarg.h>
@@ -1144,9 +1145,8 @@ ZEND_API void zend_merge_properties(zval *obj, HashTable *properties TSRMLS_DC)
if (key) {
zval member;
ZVAL_STR(&member, zend_string_copy(key));
ZVAL_STR(&member, key);
obj_ht->write_property(obj, &member, value, NULL TSRMLS_CC);
zval_ptr_dtor(&member);
}
} ZEND_HASH_FOREACH_END();
EG(scope) = old_scope;
@@ -1268,13 +1268,12 @@ ZEND_API void object_properties_init_ex(zend_object *object, HashTable *properti
{
object->properties = properties;
if (object->ce->default_properties_count) {
zval *prop, tmp;
zval *prop;
zend_string *key;
zend_property_info *property_info;
ZEND_HASH_FOREACH_STR_KEY_VAL(properties, key, prop) {
ZVAL_STR(&tmp, key);
property_info = zend_get_property_info(object->ce, &tmp, 1 TSRMLS_CC);
property_info = zend_get_property_info(object->ce, key, 1 TSRMLS_CC);
if (property_info &&
(property_info->flags & ZEND_ACC_STATIC) == 0 &&
property_info->offset >= 0) {
@@ -1293,8 +1292,7 @@ ZEND_API void object_properties_load(zend_object *object, HashTable *properties
zend_property_info *property_info;
ZEND_HASH_FOREACH_STR_KEY_VAL(properties, key, prop) {
ZVAL_STR(&tmp, key);
property_info = zend_get_property_info(object->ce, &tmp, 1 TSRMLS_CC);
property_info = zend_get_property_info(object->ce, key, 1 TSRMLS_CC);
if (property_info &&
(property_info->flags & ZEND_ACC_STATIC) == 0 &&
property_info->offset >= 0) {
@@ -1303,7 +1301,7 @@ ZEND_API void object_properties_load(zend_object *object, HashTable *properties
zval_add_ref(&object->properties_table[property_info->offset]);
if (object->properties) {
ZVAL_INDIRECT(&tmp, &object->properties_table[property_info->offset]);
prop = zend_hash_update(object->properties, key, &tmp);
zend_hash_update(object->properties, key, &tmp);
}
} else {
if (!object->properties) {
@@ -2280,7 +2278,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
/* If types of arguments have to be checked */
if (reg_function->common.arg_info && reg_function->common.num_args) {
int i;
uint32_t i;
for (i = 0; i < reg_function->common.num_args; i++) {
if (reg_function->common.arg_info[i].class_name ||
reg_function->common.arg_info[i].type_hint) {
@@ -3450,7 +3448,7 @@ ZEND_API int zend_fcall_info_init(zval *callable, uint check_flags, zend_fcall_i
ZEND_API void zend_fcall_info_args_clear(zend_fcall_info *fci, int free_mem) /* {{{ */
{
if (fci->params) {
int i;
uint32_t i;
for (i = 0; i < fci->param_count; i++) {
zval_ptr_dtor(&fci->params[i]);
@@ -3484,7 +3482,7 @@ ZEND_API void zend_fcall_info_args_restore(zend_fcall_info *fci, int param_count
ZEND_API int zend_fcall_info_args_ex(zend_fcall_info *fci, zend_function *func, zval *args TSRMLS_DC) /* {{{ */
{
zval *arg, *params;
int n = 1;
uint32_t n = 1;
zend_fcall_info_args_clear(fci, !args);

View File

@@ -46,10 +46,10 @@ typedef struct _zend_fcall_info {
zval function_name;
zend_array *symbol_table;
zval *retval;
uint32_t param_count;
zval *params;
zend_object *object;
zend_bool no_separation;
uint32_t param_count;
} zend_fcall_info;
typedef struct _zend_fcall_info_cache {
@@ -1193,7 +1193,7 @@ static zend_always_inline int _z_param_string(zval *arg, char **dest, size_t *de
static zend_always_inline int _z_param_path_str(zval *arg, zend_string **dest, int check_null TSRMLS_DC)
{
if (!_z_param_str(arg, dest, check_null TSRMLS_CC) ||
(check_null && UNEXPECTED(!(*dest)->val)) ||
(check_null && UNEXPECTED(!(*dest)->val[0])) ||
UNEXPECTED(CHECK_NULL_PATH((*dest)->val, (*dest)->len))) {
return 0;
}

View File

@@ -57,6 +57,7 @@
#include "zend_alloc.h"
#include "zend_globals.h"
#include "zend_operators.h"
#include "zend_multiply.h"
#ifdef HAVE_SIGNAL_H
# include <signal.h>
@@ -372,6 +373,30 @@ static ZEND_NORETURN void zend_mm_safe_error(zend_mm_heap *heap,
exit(1);
}
#ifdef _WIN32
void
stderr_last_error(char *msg)
{
LPSTR buf = NULL;
DWORD err = GetLastError();
if (!FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
err,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR)&buf,
0, NULL)) {
fprintf(stderr, "\n%s: [0x%08x]\n", msg, err);
}
else {
fprintf(stderr, "\n%s: [0x%08x] %s\n", msg, err, buf);
}
}
#endif
/*****************/
/* OS Allocation */
/*****************/
@@ -408,7 +433,7 @@ static void *zend_mm_mmap(size_t size)
if (ptr == NULL) {
#if ZEND_MM_ERROR
fprintf(stderr, "\nVirtualAlloc() failed: [%d]\n", GetLastError());
stderr_last_error("VirtualAlloc() failed");
#endif
return NULL;
}
@@ -431,7 +456,7 @@ static void zend_mm_munmap(void *addr, size_t size)
#ifdef _WIN32
if (VirtualFree(addr, 0, MEM_RELEASE) == 0) {
#if ZEND_MM_ERROR
fprintf(stderr, "\nVirtualFree() failed: [%d]\n", GetLastError());
stderr_last_error("VirtualFree() failed");
#endif
}
#else
@@ -452,6 +477,19 @@ static zend_always_inline int zend_mm_bitset_nts(zend_mm_bitset bitset)
{
#if defined(__GNUC__)
return __builtin_ctzl(~bitset);
#elif defined(_WIN32)
unsigned long index;
#if defined(_WIN64)
if (!BitScanForward64(&index, ~bitset)) {
#else
if (!BitScanForward(&index, ~bitset)) {
#endif
/* undefined behavior */
return 32;
}
return (int)index;
#else
int n;
@@ -476,6 +514,19 @@ static zend_always_inline int zend_mm_bitset_ntz(zend_mm_bitset bitset)
{
#if defined(__GNUC__)
return __builtin_ctzl(bitset);
#elif defined(_WIN32)
unsigned long index;
#if defined(_WIN64)
if (!BitScanForward64(&index, bitset)) {
#else
if (!BitScanForward(&index, bitset)) {
#endif
/* undefined behavior */
return 32;
}
return (int)index;
#else
int n;
@@ -882,6 +933,13 @@ not_found:
chunk = (zend_mm_chunk*)zend_mm_chunk_alloc(ZEND_MM_CHUNK_SIZE, ZEND_MM_CHUNK_SIZE);
if (UNEXPECTED(chunk == NULL)) {
/* insufficient memory */
#if !ZEND_MM_LIMIT
zend_mm_safe_error(heap, "Out of memory");
#elif ZEND_DEBUG
zend_mm_safe_error(heap, "Out of memory (allocated %ld) at %s:%d (tried to allocate %lu bytes)", heap->real_size, __zend_filename, __zend_lineno, size);
#else
zend_mm_safe_error(heap, "Out of memory (allocated %ld) (tried to allocate %lu bytes)", heap->real_size, ZEND_MM_PAGE_SIZE * pages_count);
#endif
return NULL;
}
#if ZEND_MM_STAT
@@ -986,14 +1044,22 @@ static zend_always_inline void zend_mm_free_large(zend_mm_heap *heap, zend_mm_ch
/* Small Runs */
/**************/
/* higher set bit number (0->0, 1->1, 2->2, 4->3, 8->4, 127->7, 128->8 etc) */
/* higher set bit number (0->N/A, 1->1, 2->2, 4->3, 8->4, 127->7, 128->8 etc) */
static zend_always_inline int zend_mm_small_size_to_bit(int size)
{
#if defined(__GNUC__)
return (__builtin_clz(size) ^ 0x1f) + 1;
#elif defined(_WIN32)
unsigned long index;
if (!BitScanReverse(&index, (unsigned long)size)) {
/* undefined behavior */
return 64;
}
return (((31 - (int)index) ^ 0x1f) + 1);
#else
int n = 16;
if (size == 0) return 0;
if (size <= 0x00ff) {n -= 8; size = size << 8;}
if (size <= 0x0fff) {n -= 4; size = size << 4;}
if (size <= 0x3fff) {n -= 2; size = size << 2;}
@@ -1546,6 +1612,13 @@ static void *zend_mm_alloc_huge(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_D
ptr = zend_mm_chunk_alloc(new_size, ZEND_MM_CHUNK_SIZE);
if (UNEXPECTED(ptr == NULL)) {
/* insufficient memory */
#if !ZEND_MM_LIMIT
zend_mm_safe_error(heap, "Out of memory");
#elif ZEND_DEBUG
zend_mm_safe_error(heap, "Out of memory (allocated %ld) at %s:%d (tried to allocate %lu bytes)", heap->real_size, __zend_filename, __zend_lineno, size);
#else
zend_mm_safe_error(heap, "Out of memory (allocated %ld) (tried to allocate %lu bytes)", heap->real_size, size);
#endif
return NULL;
}
#if ZEND_DEBUG
@@ -1598,7 +1671,11 @@ zend_mm_heap *zend_mm_init(void)
if (UNEXPECTED(chunk == NULL)) {
#if ZEND_MM_ERROR
#ifdef _WIN32
stderr_last_error("Can't initialize heap");
#else
fprintf(stderr, "\nCan't initialize heap: [%d] %s\n", errno, strerror(errno));
#endif
#endif
return NULL;
}
@@ -2080,125 +2157,18 @@ ZEND_API size_t ZEND_FASTCALL _zend_mem_block_size(void *ptr TSRMLS_DC ZEND_FILE
return zend_mm_size(AG(mm_heap), ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
}
#if defined(__GNUC__) && (defined(__native_client__) || defined(i386))
static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
static zend_always_inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
{
size_t res = nmemb;
zend_ulong overflow = 0;
__asm__ ("mull %3\n\taddl %4,%0\n\tadcl $0,%1"
: "=&a"(res), "=&d" (overflow)
: "%0"(res),
"rm"(size),
"rm"(offset));
int overflow;
size_t ret = zend_safe_address(nmemb, size, offset, &overflow);
if (UNEXPECTED(overflow)) {
zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
return 0;
}
return res;
return ret;
}
#elif defined(__GNUC__) && defined(__x86_64__)
static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
{
size_t res = nmemb;
zend_ulong overflow = 0;
#ifdef __ILP32__ /* x32 */
# define LP_SUFF "l"
#else /* amd64 */
# define LP_SUFF "q"
#endif
__asm__ ("mul" LP_SUFF " %3\n\t"
"add %4,%0\n\t"
"adc $0,%1"
: "=&a"(res), "=&d" (overflow)
: "%0"(res),
"rm"(size),
"rm"(offset));
#undef LP_SUFF
if (UNEXPECTED(overflow)) {
zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
return 0;
}
return res;
}
#elif defined(__GNUC__) && defined(__arm__)
static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
{
size_t res;
zend_ulong overflow;
__asm__ ("umlal %0,%1,%2,%3"
: "=r"(res), "=r"(overflow)
: "r"(nmemb),
"r"(size),
"0"(offset),
"1"(0));
if (UNEXPECTED(overflow)) {
zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
return 0;
}
return res;
}
#elif defined(__GNUC__) && defined(__aarch64__)
static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
{
size_t res;
zend_ulong overflow;
__asm__ ("mul %0,%2,%3\n\tumulh %1,%2,%3\n\tadds %0,%0,%4\n\tadc %1,%1,xzr"
: "=&r"(res), "=&r"(overflow)
: "r"(nmemb),
"r"(size),
"r"(offset));
if (UNEXPECTED(overflow)) {
zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
return 0;
}
return res;
}
#elif SIZEOF_SIZE_T == 4 && defined(HAVE_ZEND_LONG64)
static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
{
zend_ulong64 res = (zend_ulong64)nmemb * (zend_ulong64)size + (zend_ulong64)offset;
if (UNEXPECTED(res > (zend_ulong64)0xFFFFFFFFL)) {
zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
return 0;
}
return (size_t) res;
}
#else
static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
{
size_t res = nmemb * size + offset;
double _d = (double)nmemb * (double)size + (double)offset;
double _delta = (double)res - _d;
if (UNEXPECTED((_d + _delta ) != _d)) {
zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
return 0;
}
return res;
}
#endif
ZEND_API void* ZEND_FASTCALL _safe_emalloc(size_t nmemb, size_t size, size_t offset ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
{

View File

@@ -45,8 +45,8 @@ typedef struct _zend_leak_info {
void *addr;
size_t size;
const char *filename;
uint lineno;
const char *orig_filename;
uint lineno;
uint orig_lineno;
} zend_leak_info;
@@ -164,7 +164,7 @@ ZEND_API void ZEND_FASTCALL _efree_huge(void *, size_t size);
#define estrndup_rel(s, length) _estrndup((s), (length) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
#define zend_mem_block_size_rel(ptr) _zend_mem_block_size((ptr) TSRMLS_CC ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
inline static void * __zend_malloc(size_t len)
zend_always_inline static void * __zend_malloc(size_t len)
{
void *tmp = malloc(len);
if (tmp) {
@@ -174,14 +174,14 @@ inline static void * __zend_malloc(size_t len)
exit(1);
}
inline static void * __zend_calloc(size_t nmemb, size_t len)
zend_always_inline static void * __zend_calloc(size_t nmemb, size_t len)
{
void *tmp = _safe_malloc(nmemb, len, 0);
memset(tmp, 0, nmemb * len);
return tmp;
}
inline static void * __zend_realloc(void *p, size_t len)
zend_always_inline static void * __zend_realloc(void *p, size_t len)
{
p = realloc(p, len);
if (p) {
@@ -220,8 +220,6 @@ ZEND_API int is_zend_mm(TSRMLS_D);
ZEND_API size_t zend_memory_usage(int real_usage TSRMLS_DC);
ZEND_API size_t zend_memory_peak_usage(int real_usage TSRMLS_DC);
END_EXTERN_C()
/* fast cache for HashTables */
#define ALLOC_HASHTABLE(ht) \
(ht) = (HashTable *) emalloc(sizeof(HashTable))
@@ -262,6 +260,8 @@ ZEND_API void zend_mm_set_custom_handlers(zend_mm_heap *heap,
void (*_free)(void*),
void* (*_realloc)(void*, size_t));
END_EXTERN_C()
#endif
/*

View File

@@ -65,7 +65,7 @@ static zend_always_inline void* zend_arena_alloc(zend_arena **arena_ptr, size_t
size_t arena_size =
UNEXPECTED((size + ZEND_MM_ALIGNED_SIZE(sizeof(zend_arena))) > (size_t)(arena->end - (char*) arena)) ?
(size + ZEND_MM_ALIGNED_SIZE(sizeof(zend_arena))) :
(arena->end - (char*) arena);
(size_t)(arena->end - (char*) arena);
zend_arena *new_arena = (zend_arena*)emalloc(arena_size);
ptr = (char*) new_arena + ZEND_MM_ALIGNED_SIZE(sizeof(zend_arena));
@@ -80,10 +80,14 @@ static zend_always_inline void* zend_arena_alloc(zend_arena **arena_ptr, size_t
static zend_always_inline void* zend_arena_calloc(zend_arena **arena_ptr, size_t count, size_t unit_size)
{
size_t size = unit_size * count;
int overflow;
size_t size;
void *ret;
ZEND_ASSERT(size >= unit_size && size >= count);
size = zend_safe_address(unit_size, count, 0, &overflow);
if (UNEXPECTED(overflow)) {
zend_error(E_ERROR, "Possible integer overflow in zend_arena_calloc() (%zu * %zu)", unit_size, count);
}
ret = zend_arena_alloc(arena_ptr, size);
memset(ret, 0, size);
return ret;

View File

@@ -42,8 +42,10 @@ static inline size_t zend_ast_list_size(uint32_t children) {
}
ZEND_API zend_ast *zend_ast_create_znode(znode *node) {
zend_ast_znode *ast;
TSRMLS_FETCH();
zend_ast_znode *ast = zend_ast_alloc(sizeof(zend_ast_znode) TSRMLS_CC);
ast = zend_ast_alloc(sizeof(zend_ast_znode) TSRMLS_CC);
ast->kind = ZEND_AST_ZNODE;
ast->attr = 0;
ast->lineno = CG(zend_lineno);
@@ -52,8 +54,10 @@ ZEND_API zend_ast *zend_ast_create_znode(znode *node) {
}
ZEND_API zend_ast *zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr) {
zend_ast_zval *ast;
TSRMLS_FETCH();
zend_ast_zval *ast = zend_ast_alloc(sizeof(zend_ast_zval) TSRMLS_CC);
ast = zend_ast_alloc(sizeof(zend_ast_zval) TSRMLS_CC);
ast->kind = ZEND_AST_ZVAL;
ast->attr = attr;
ZVAL_COPY_VALUE(&ast->val, zv);
@@ -65,9 +69,10 @@ ZEND_API zend_ast *zend_ast_create_decl(
zend_ast_kind kind, uint32_t flags, uint32_t start_lineno, zend_string *doc_comment,
zend_string *name, zend_ast *child0, zend_ast *child1, zend_ast *child2
) {
zend_ast_decl *ast;
TSRMLS_FETCH();
zend_ast_decl *ast = zend_ast_alloc(sizeof(zend_ast_decl) TSRMLS_CC);
ast = zend_ast_alloc(sizeof(zend_ast_decl) TSRMLS_CC);
ast->kind = kind;
ast->attr = 0;
ast->start_lineno = start_lineno;
@@ -84,9 +89,11 @@ ZEND_API zend_ast *zend_ast_create_decl(
}
static zend_ast *zend_ast_create_from_va_list(zend_ast_kind kind, zend_ast_attr attr, va_list va) {
TSRMLS_FETCH();
uint32_t i, children = kind >> ZEND_AST_NUM_CHILDREN_SHIFT;
zend_ast *ast = zend_ast_alloc(zend_ast_size(children) TSRMLS_CC);
zend_ast *ast;
TSRMLS_FETCH();
ast = zend_ast_alloc(zend_ast_size(children) TSRMLS_CC);
ast->kind = kind;
ast->attr = attr;
ast->lineno = (uint32_t) -1;
@@ -131,10 +138,12 @@ ZEND_API zend_ast *zend_ast_create(zend_ast_kind kind, ...) {
}
ZEND_API zend_ast *zend_ast_create_list(uint32_t init_children, zend_ast_kind kind, ...) {
zend_ast *ast;
zend_ast_list *list;
TSRMLS_FETCH();
zend_ast *ast = zend_ast_alloc(zend_ast_list_size(4) TSRMLS_CC);
zend_ast_list *list = (zend_ast_list *) ast;
ast = zend_ast_alloc(zend_ast_list_size(4) TSRMLS_CC);
list = (zend_ast_list *) ast;
list->kind = kind;
list->attr = 0;
list->lineno = CG(zend_lineno);
@@ -154,7 +163,7 @@ ZEND_API zend_ast *zend_ast_create_list(uint32_t init_children, zend_ast_kind ki
}
static inline zend_bool is_power_of_two(uint32_t n) {
return n == (n & -n);
return ((n != 0) && (n == (n & (~n + 1))));
}
ZEND_API zend_ast *zend_ast_list_add(zend_ast *ast, zend_ast *op) {
@@ -373,16 +382,11 @@ static void zend_ast_destroy_ex(zend_ast *ast, zend_bool free) {
switch (ast->kind) {
case ZEND_AST_ZVAL:
{
/* Destroy value without using GC: When opcache moves arrays into SHM it will
* free the zend_array structure, so references to it from outside the op array
* become invalid. GC would cause such a reference in the root buffer. */
zval *zv = zend_ast_get_zval(ast);
if (Z_REFCOUNTED_P(zv) && !Z_DELREF_P(zv)) {
_zval_dtor_func_for_ptr(Z_COUNTED_P(zv) ZEND_FILE_LINE_CC);
}
zval_ptr_dtor_nogc(zend_ast_get_zval(ast));
break;
}
case ZEND_AST_FUNC_DECL:
case ZEND_AST_CLOSURE:
case ZEND_AST_METHOD:

View File

@@ -207,27 +207,27 @@ ZEND_API void zend_ast_destroy_and_free(zend_ast *ast);
typedef void (*zend_ast_apply_func)(zend_ast **ast_ptr TSRMLS_DC);
ZEND_API void zend_ast_apply(zend_ast *ast, zend_ast_apply_func fn TSRMLS_DC);
static inline zend_bool zend_ast_is_list(zend_ast *ast) {
static zend_always_inline zend_bool zend_ast_is_list(zend_ast *ast) {
return (ast->kind >> ZEND_AST_IS_LIST_SHIFT) & 1;
}
static inline zend_ast_list *zend_ast_get_list(zend_ast *ast) {
static zend_always_inline zend_ast_list *zend_ast_get_list(zend_ast *ast) {
ZEND_ASSERT(zend_ast_is_list(ast));
return (zend_ast_list *) ast;
}
static inline zval *zend_ast_get_zval(zend_ast *ast) {
static zend_always_inline zval *zend_ast_get_zval(zend_ast *ast) {
ZEND_ASSERT(ast->kind == ZEND_AST_ZVAL);
return &((zend_ast_zval *) ast)->val;
}
static inline zend_string *zend_ast_get_str(zend_ast *ast) {
static zend_always_inline zend_string *zend_ast_get_str(zend_ast *ast) {
return Z_STR_P(zend_ast_get_zval(ast));
}
static inline uint32_t zend_ast_get_num_children(zend_ast *ast) {
static zend_always_inline uint32_t zend_ast_get_num_children(zend_ast *ast) {
ZEND_ASSERT(!zend_ast_is_list(ast));
return ast->kind >> ZEND_AST_NUM_CHILDREN_SHIFT;
}
static inline uint32_t zend_ast_get_lineno(zend_ast *ast) {
static zend_always_inline uint32_t zend_ast_get_lineno(zend_ast *ast) {
if (ast->kind == ZEND_AST_ZVAL) {
zval *zv = zend_ast_get_zval(ast);
return zv->u2.lineno;
@@ -236,27 +236,27 @@ static inline uint32_t zend_ast_get_lineno(zend_ast *ast) {
}
}
static inline zend_ast *zend_ast_create_zval(zval *zv) {
static zend_always_inline zend_ast *zend_ast_create_zval(zval *zv) {
return zend_ast_create_zval_ex(zv, 0);
}
static inline zend_ast *zend_ast_create_zval_from_str(zend_string *str) {
static zend_always_inline zend_ast *zend_ast_create_zval_from_str(zend_string *str) {
zval zv;
ZVAL_STR(&zv, str);
return zend_ast_create_zval(&zv);
}
static inline zend_ast *zend_ast_create_zval_from_long(zend_long lval) {
static zend_always_inline zend_ast *zend_ast_create_zval_from_long(zend_long lval) {
zval zv;
ZVAL_LONG(&zv, lval);
return zend_ast_create_zval(&zv);
}
static inline zend_ast *zend_ast_create_binary_op(uint32_t opcode, zend_ast *op0, zend_ast *op1) {
static zend_always_inline zend_ast *zend_ast_create_binary_op(uint32_t opcode, zend_ast *op0, zend_ast *op1) {
return zend_ast_create_ex(ZEND_AST_BINARY_OP, opcode, op0, op1);
}
static inline zend_ast *zend_ast_create_assign_op(uint32_t opcode, zend_ast *op0, zend_ast *op1) {
static zend_always_inline zend_ast *zend_ast_create_assign_op(uint32_t opcode, zend_ast *op0, zend_ast *op1) {
return zend_ast_create_ex(ZEND_AST_ASSIGN_OP, opcode, op0, op1);
}
static inline zend_ast *zend_ast_create_cast(uint32_t type, zend_ast *op0) {
static zend_always_inline zend_ast *zend_ast_create_cast(uint32_t type, zend_ast *op0) {
return zend_ast_create_ex(ZEND_AST_CAST, type, op0);
}

View File

@@ -381,7 +381,7 @@ ZEND_FUNCTION(gc_enabled)
ZEND_FUNCTION(gc_enable)
{
zend_string *key = zend_string_init("zend.enable_gc", sizeof("zend.enable_gc")-1, 0);
zend_alter_ini_entry(key, "1", sizeof("1")-1, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
zend_alter_ini_entry_chars(key, "1", sizeof("1")-1, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
zend_string_release(key);
}
/* }}} */
@@ -391,7 +391,7 @@ ZEND_FUNCTION(gc_enable)
ZEND_FUNCTION(gc_disable)
{
zend_string *key = zend_string_init("zend.enable_gc", sizeof("zend.enable_gc")-1, 0);
zend_alter_ini_entry(key, "0", sizeof("0")-1, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
zend_alter_ini_entry_chars(key, "0", sizeof("0")-1, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
zend_string_release(key);
}
/* }}} */
@@ -415,7 +415,7 @@ ZEND_FUNCTION(func_num_args)
Get the $arg_num'th argument that was passed to the function */
ZEND_FUNCTION(func_get_arg)
{
int arg_count, first_extra_arg;
uint32_t arg_count, first_extra_arg;
zval *arg;
zend_long requested_offset;
zend_execute_data *ex;
@@ -460,8 +460,8 @@ ZEND_FUNCTION(func_get_arg)
ZEND_FUNCTION(func_get_args)
{
zval *p;
int arg_count, first_extra_arg;
int i;
uint32_t arg_count, first_extra_arg;
uint32_t i;
zend_execute_data *ex = EG(current_execute_data)->prev_execute_data;
if (ex->frame_kind != VM_FRAME_NESTED_FUNCTION && ex->frame_kind != VM_FRAME_TOP_FUNCTION) {
@@ -539,7 +539,6 @@ ZEND_FUNCTION(strlen)
}
/* }}} */
/* {{{ proto int strcmp(string str1, string str2)
Binary safe string comparison */
ZEND_FUNCTION(strcmp)
@@ -554,7 +553,6 @@ ZEND_FUNCTION(strcmp)
}
/* }}} */
/* {{{ proto int strncmp(string str1, string str2, int len)
Binary safe string comparison */
ZEND_FUNCTION(strncmp)
@@ -575,7 +573,6 @@ ZEND_FUNCTION(strncmp)
}
/* }}} */
/* {{{ proto int strcasecmp(string str1, string str2)
Binary safe case-insensitive string comparison */
ZEND_FUNCTION(strcasecmp)
@@ -590,7 +587,6 @@ ZEND_FUNCTION(strcasecmp)
}
/* }}} */
/* {{{ proto int strncasecmp(string str1, string str2, int len)
Binary safe string comparison */
ZEND_FUNCTION(strncasecmp)
@@ -611,7 +607,6 @@ ZEND_FUNCTION(strncasecmp)
}
/* }}} */
/* {{{ proto array each(array arr)
Return the currently pointed key..value pair in the passed array, and advance the pointer to the next element */
ZEND_FUNCTION(each)
@@ -660,7 +655,7 @@ ZEND_FUNCTION(each)
/* add the key elements */
if (zend_hash_get_current_key(target_hash, &key, &num_key, 0) == HASH_KEY_IS_STRING) {
ZVAL_STR(&tmp, zend_string_copy(key));
ZVAL_STR_COPY(&tmp, key);
if (Z_REFCOUNTED(tmp)) Z_ADDREF(tmp);
} else {
ZVAL_LONG(&tmp, num_key);
@@ -671,23 +666,21 @@ ZEND_FUNCTION(each)
}
/* }}} */
/* {{{ proto int error_reporting([int new_error_level])
Return the current error_reporting level, and if an argument was passed - change to the new level */
ZEND_FUNCTION(error_reporting)
{
char *err;
size_t err_len;
zend_string *err;
int old_error_reporting;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &err, &err_len) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|S", &err) == FAILURE) {
return;
}
old_error_reporting = EG(error_reporting);
if(ZEND_NUM_ARGS() != 0) {
zend_string *key = zend_string_init("error_reporting", sizeof("error_reporting")-1, 0);
zend_alter_ini_entry(key, err, err_len, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
zend_alter_ini_entry(key, err, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
zend_string_release(key);
}
@@ -695,7 +688,6 @@ ZEND_FUNCTION(error_reporting)
}
/* }}} */
/* {{{ proto bool define(string constant_name, mixed value, boolean case_insensitive=false)
Define a new constant */
ZEND_FUNCTION(define)
@@ -775,7 +767,6 @@ repeat:
}
/* }}} */
/* {{{ proto bool defined(string constant_name)
Check whether a constant exists
Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
@@ -801,7 +792,6 @@ ZEND_FUNCTION(defined)
}
/* }}} */
/* {{{ proto string get_class([object object])
Retrieves the class name */
ZEND_FUNCTION(get_class)
@@ -825,7 +815,6 @@ ZEND_FUNCTION(get_class)
}
/* }}} */
/* {{{ proto string get_called_class()
Retrieves the "Late Static Binding" class name */
ZEND_FUNCTION(get_called_class)
@@ -843,7 +832,6 @@ ZEND_FUNCTION(get_called_class)
}
/* }}} */
/* {{{ proto string get_parent_class([mixed object])
Retrieves the parent class name for object or class or current scope. */
ZEND_FUNCTION(get_parent_class)
@@ -884,8 +872,7 @@ ZEND_FUNCTION(get_parent_class)
}
/* }}} */
static void is_a_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool only_subclass)
static void is_a_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool only_subclass) /* {{{ */
{
zval *obj;
zend_string *class_name;
@@ -937,7 +924,7 @@ static void is_a_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool only_subclass)
RETURN_BOOL(retval);
}
/* }}} */
/* {{{ proto bool is_subclass_of(mixed object_or_string, string class_name [, bool allow_string=true])
Returns true if the object has this class as one of its parents */
@@ -947,7 +934,6 @@ ZEND_FUNCTION(is_subclass_of)
}
/* }}} */
/* {{{ proto bool is_a(mixed object_or_string, string class_name [, bool allow_string=false])
Returns true if the first argument is an object and is this class or has this class as one of its parents, */
ZEND_FUNCTION(is_a)
@@ -956,7 +942,6 @@ ZEND_FUNCTION(is_a)
}
/* }}} */
/* {{{ add_class_vars */
static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value TSRMLS_DC)
{
@@ -1004,7 +989,6 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value
}
/* }}} */
/* {{{ proto array get_class_vars(string class_name)
Returns an array of default properties of the class. */
ZEND_FUNCTION(get_class_vars)
@@ -1028,7 +1012,6 @@ ZEND_FUNCTION(get_class_vars)
}
/* }}} */
/* {{{ proto array get_object_vars(object obj)
Returns an array of object properties */
ZEND_FUNCTION(get_object_vars)
@@ -1037,8 +1020,6 @@ ZEND_FUNCTION(get_object_vars)
zval *value;
HashTable *properties;
zend_string *key;
const char *prop_name, *class_name;
uint prop_len;
zend_object *zobj;
#ifndef FAST_ZPP
@@ -1063,7 +1044,7 @@ ZEND_FUNCTION(get_object_vars)
zobj = Z_OBJ_P(obj);
array_init(return_value);
array_init_size(return_value, zend_hash_num_elements(properties));
ZEND_HASH_FOREACH_STR_KEY_VAL_IND(properties, key, value) {
if (key) {
@@ -1071,7 +1052,9 @@ ZEND_FUNCTION(get_object_vars)
/* Not separating references */
if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
if (key->val[0] == 0) {
zend_unmangle_property_name_ex(key->val, key->len, &class_name, &prop_name, (int*) &prop_len);
const char *prop_name, *class_name;
size_t prop_len;
zend_unmangle_property_name_ex(key, &class_name, &prop_name, &prop_len);
zend_hash_str_add_new(Z_ARRVAL_P(return_value), prop_name, prop_len, value);
} else {
zend_hash_add_new(Z_ARRVAL_P(return_value), key, value);
@@ -1082,13 +1065,14 @@ ZEND_FUNCTION(get_object_vars)
}
/* }}} */
static int same_name(const char *key, const char *name, uint32_t name_len)
static int same_name(const char *key, const char *name, uint32_t name_len) /* {{{ */
{
char *lcname = zend_str_tolower_dup(name, name_len);
int ret = memcmp(lcname, key, name_len) == 0;
efree(lcname);
return ret;
}
/* }}} */
/* {{{ proto array get_class_methods(mixed class)
Returns an array of method names for class or class instance. */
@@ -1132,7 +1116,7 @@ ZEND_FUNCTION(get_class_methods)
/* Do not display old-style inherited constructors */
if (!key) {
ZVAL_STR(&method_name, zend_string_copy(mptr->common.function_name));
ZVAL_STR_COPY(&method_name, mptr->common.function_name);
zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &method_name);
} else if ((mptr->common.fn_flags & ZEND_ACC_CTOR) == 0 ||
mptr->common.scope == ce ||
@@ -1142,10 +1126,10 @@ ZEND_FUNCTION(get_class_methods)
*mptr->op_array.refcount > 1 &&
(len != key->len ||
!same_name(key->val, mptr->common.function_name->val, len))) {
ZVAL_STR(&method_name, zend_string_copy(zend_find_alias_name(mptr->common.scope, key)));
ZVAL_STR_COPY(&method_name, zend_find_alias_name(mptr->common.scope, key));
zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &method_name);
} else {
ZVAL_STR(&method_name, zend_string_copy(mptr->common.function_name));
ZVAL_STR_COPY(&method_name, mptr->common.function_name);
zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &method_name);
}
}
@@ -1154,7 +1138,6 @@ ZEND_FUNCTION(get_class_methods)
}
/* }}} */
/* {{{ proto bool method_exists(object object, string method)
Checks if the class method exists */
ZEND_FUNCTION(method_exists)
@@ -1263,7 +1246,6 @@ ZEND_FUNCTION(property_exists)
}
/* }}} */
/* {{{ proto bool class_exists(string classname [, bool autoload])
Checks if the class exists */
ZEND_FUNCTION(class_exists)
@@ -1394,7 +1376,6 @@ ZEND_FUNCTION(trait_exists)
}
/* }}} */
/* {{{ proto bool function_exists(string function_name)
Checks if the function exists */
ZEND_FUNCTION(function_exists)
@@ -1538,7 +1519,6 @@ ZEND_FUNCTION(get_included_files)
}
/* }}} */
/* {{{ proto void trigger_error(string message [, int error_type])
Generates a user-level error/warning/notice message */
ZEND_FUNCTION(trigger_error)
@@ -1568,7 +1548,6 @@ ZEND_FUNCTION(trigger_error)
}
/* }}} */
/* {{{ proto string set_error_handler(string error_handler [, int error_types])
Sets a user-defined error handler function. Returns the previously defined error handler, or false on error */
ZEND_FUNCTION(set_error_handler)
@@ -1608,7 +1587,6 @@ ZEND_FUNCTION(set_error_handler)
}
/* }}} */
/* {{{ proto void restore_error_handler(void)
Restores the previously defined error handler function */
ZEND_FUNCTION(restore_error_handler)
@@ -1635,7 +1613,6 @@ ZEND_FUNCTION(restore_error_handler)
}
/* }}} */
/* {{{ proto string set_exception_handler(callable exception_handler)
Sets a user-defined exception handler function. Returns the previously defined exception handler, or false on error */
ZEND_FUNCTION(set_exception_handler)
@@ -1672,7 +1649,6 @@ ZEND_FUNCTION(set_exception_handler)
}
/* }}} */
/* {{{ proto void restore_exception_handler(void)
Restores the previously defined exception handler function */
ZEND_FUNCTION(restore_exception_handler)
@@ -1691,7 +1667,7 @@ ZEND_FUNCTION(restore_exception_handler)
}
/* }}} */
static int copy_class_or_interface_name(zval *el TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
static int copy_class_or_interface_name(zval *el TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
{
zend_class_entry *ce = (zend_class_entry *)Z_PTR_P(el);
zval *array = va_arg(args, zval *);
@@ -1711,6 +1687,7 @@ static int copy_class_or_interface_name(zval *el TSRMLS_DC, int num_args, va_lis
}
return ZEND_HASH_APPLY_KEEP;
}
/* }}} */
/* {{{ proto array get_declared_traits()
Returns an array of all declared traits. */
@@ -1728,7 +1705,6 @@ ZEND_FUNCTION(get_declared_traits)
}
/* }}} */
/* {{{ proto array get_declared_classes()
Returns an array of all declared classes. */
ZEND_FUNCTION(get_declared_classes)
@@ -1761,8 +1737,7 @@ ZEND_FUNCTION(get_declared_interfaces)
}
/* }}} */
static int copy_function_name(zval *zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
static int copy_function_name(zval *zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
{
zend_function *func = Z_PTR_P(zv);
zval *internal_ar = va_arg(args, zval *),
@@ -1780,7 +1755,7 @@ static int copy_function_name(zval *zv TSRMLS_DC, int num_args, va_list args, ze
return 0;
}
/* }}} */
/* {{{ proto array get_defined_functions(void)
Returns an array of all defined functions */
@@ -1818,7 +1793,6 @@ ZEND_FUNCTION(get_defined_functions)
}
/* }}} */
/* {{{ proto array get_defined_vars(void)
Returns an associative array of names and values of all currently defined variable names (variables in the current scope) */
ZEND_FUNCTION(get_defined_vars)
@@ -1830,7 +1804,6 @@ ZEND_FUNCTION(get_defined_vars)
}
/* }}} */
#define LAMBDA_TEMP_FUNCNAME "__lambda_func"
/* {{{ proto string create_function(string args, string code)
Creates an anonymous function, and returns its name (funny, eh?) */
@@ -1901,7 +1874,6 @@ ZEND_FUNCTION(create_function)
}
/* }}} */
#if ZEND_DEBUG
ZEND_FUNCTION(zend_test_func)
{
@@ -1987,22 +1959,24 @@ ZEND_FUNCTION(get_resources)
}
/* }}} */
static int add_extension_info(zval *item, void *arg TSRMLS_DC)
static int add_extension_info(zval *item, void *arg TSRMLS_DC) /* {{{ */
{
zval *name_array = (zval *)arg;
zend_module_entry *module = (zend_module_entry*)Z_PTR_P(item);
add_next_index_string(name_array, module->name);
return 0;
}
/* }}} */
static int add_zendext_info(zend_extension *ext, void *arg TSRMLS_DC)
static int add_zendext_info(zend_extension *ext, void *arg TSRMLS_DC) /* {{{ */
{
zval *name_array = (zval *)arg;
add_next_index_string(name_array, ext->name);
return 0;
}
/* }}} */
static int add_constant_info(zval *item, void *arg TSRMLS_DC)
static int add_constant_info(zval *item, void *arg TSRMLS_DC) /* {{{ */
{
zval *name_array = (zval *)arg;
zend_constant *constant = (zend_constant*)Z_PTR_P(item);
@@ -2017,7 +1991,7 @@ static int add_constant_info(zval *item, void *arg TSRMLS_DC)
zend_hash_add_new(Z_ARRVAL_P(name_array), constant->name, &const_val);
return 0;
}
/* }}} */
/* {{{ proto array get_loaded_extensions([bool zend_extensions]) U
Return an array containing names of loaded extensions */
@@ -2039,7 +2013,6 @@ ZEND_FUNCTION(get_loaded_extensions)
}
/* }}} */
/* {{{ proto array get_defined_constants([bool categorize])
Return an array containing the names and values of all defined constants */
ZEND_FUNCTION(get_defined_constants)
@@ -2102,18 +2075,17 @@ ZEND_FUNCTION(get_defined_constants)
}
/* }}} */
static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array TSRMLS_DC)
static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array TSRMLS_DC) /* {{{ */
{
int num_args = call->num_args;
uint32_t num_args = call->num_args;
array_init_size(arg_array, num_args);
if (num_args) {
int i = 0;
uint32_t i = 0;
zval *p = ZEND_CALL_ARG(call, 1);
if (call->func->type == ZEND_USER_FUNCTION) {
int first_extra_arg = call->func->op_array.num_args;
uint32_t first_extra_arg = call->func->op_array.num_args;
if (call->func->op_array.fn_flags & ZEND_ACC_VARIADIC) {
first_extra_arg--;
@@ -2137,8 +2109,9 @@ static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array TS
}
}
}
/* }}} */
void debug_print_backtrace_args(zval *arg_array TSRMLS_DC)
void debug_print_backtrace_args(zval *arg_array TSRMLS_DC) /* {{{ */
{
zval *tmp;
int i = 0;
@@ -2150,6 +2123,7 @@ void debug_print_backtrace_args(zval *arg_array TSRMLS_DC)
zend_print_flat_zval_r(tmp TSRMLS_CC);
} ZEND_HASH_FOREACH_END();
}
/* }}} */
/* {{{ proto void debug_print_backtrace([int options[, int limit]]) */
ZEND_FUNCTION(debug_print_backtrace)
@@ -2340,7 +2314,7 @@ ZEND_FUNCTION(debug_print_backtrace)
/* }}} */
ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int options, int limit TSRMLS_DC)
ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int options, int limit TSRMLS_DC) /* {{{ */
{
zend_execute_data *call, *ptr, *skip;
zend_object *object;
@@ -2548,7 +2522,6 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
}
/* }}} */
/* {{{ proto array debug_backtrace([int options[, int limit]])
Return backtrace as array */
ZEND_FUNCTION(debug_backtrace)
@@ -2587,7 +2560,6 @@ ZEND_FUNCTION(extension_loaded)
}
/* }}} */
/* {{{ proto array get_extension_funcs(string extension_name)
Returns an array with the names of functions belonging to the named extension */
ZEND_FUNCTION(get_extension_funcs)

View File

@@ -376,7 +376,7 @@ static HashTable *zend_closure_get_debug_info(zval *object, int *is_temp TSRMLS_
arg_info->pass_by_reference ? "&" : "",
i + 1);
}
ZVAL_STR(&info, zend_strpprintf(0, "%s", i >= required ? "<optional>" : "<required>"));
ZVAL_NEW_STR(&info, zend_strpprintf(0, "%s", i >= required ? "<optional>" : "<required>"));
zend_hash_update(Z_ARRVAL(val), name, &info);
zend_string_release(name);
arg_info++;

File diff suppressed because it is too large Load Diff

View File

@@ -83,7 +83,7 @@ typedef struct _zend_ast_znode {
} zend_ast_znode;
ZEND_API zend_ast *zend_ast_create_znode(znode *node);
static inline znode *zend_ast_get_znode(zend_ast *ast) {
static zend_always_inline znode *zend_ast_get_znode(zend_ast *ast) {
return &((zend_ast_znode *) ast)->node;
}
@@ -449,14 +449,6 @@ void zend_do_free(znode *op1 TSRMLS_DC);
ZEND_API int do_bind_function(const zend_op_array *op_array, const zend_op *opline, HashTable *function_table, zend_bool compile_time TSRMLS_DC);
ZEND_API zend_class_entry *do_bind_class(const zend_op_array *op_array, const zend_op *opline, HashTable *class_table, zend_bool compile_time TSRMLS_DC);
ZEND_API zend_class_entry *do_bind_inherited_class(const zend_op_array *op_array, const zend_op *opline, HashTable *class_table, zend_class_entry *parent_ce, zend_bool compile_time TSRMLS_DC);
ZEND_API void zend_do_inherit_interfaces(zend_class_entry *ce, const zend_class_entry *iface TSRMLS_DC);
ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry *iface TSRMLS_DC);
ZEND_API void zend_do_implement_trait(zend_class_entry *ce, zend_class_entry *trait TSRMLS_DC);
ZEND_API void zend_do_bind_traits(zend_class_entry *ce TSRMLS_DC);
ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent_ce TSRMLS_DC);
void zend_do_early_binding(TSRMLS_D);
ZEND_API void zend_do_delayed_early_binding(const zend_op_array *op_array TSRMLS_DC);
/* Functions for a null terminated pointer list, used for traits parsing and compilation */
@@ -491,16 +483,18 @@ ZEND_API void zend_cleanup_user_class_data(zend_class_entry *ce TSRMLS_DC);
ZEND_API void zend_cleanup_internal_class_data(zend_class_entry *ce TSRMLS_DC);
ZEND_API void zend_cleanup_internal_classes(TSRMLS_D);
ZEND_API void zend_cleanup_op_array_data(zend_op_array *op_array);
ZEND_API int clean_non_persistent_function_full(zval *zv TSRMLS_DC);
ZEND_API int clean_non_persistent_class_full(zval *zv TSRMLS_DC);
ZEND_API void destroy_zend_function(zend_function *function TSRMLS_DC);
ZEND_API void zend_function_dtor(zval *zv);
ZEND_API void destroy_zend_class(zval *zv);
void zend_class_add_ref(zval *zv);
ZEND_API zend_string *zend_mangle_property_name(const char *src1, int src1_length, const char *src2, int src2_length, int internal);
#define zend_unmangle_property_name(mangled_property, mangled_property_len, class_name, prop_name) \
zend_unmangle_property_name_ex(mangled_property, mangled_property_len, class_name, prop_name, NULL)
ZEND_API int zend_unmangle_property_name_ex(const char *mangled_property, int mangled_property_len, const char **class_name, const char **prop_name, int *prop_len);
ZEND_API zend_string *zend_mangle_property_name(const char *src1, size_t src1_length, const char *src2, size_t src2_length, int internal);
#define zend_unmangle_property_name(mangled_property, class_name, prop_name) \
zend_unmangle_property_name_ex(mangled_property, class_name, prop_name, NULL)
ZEND_API int zend_unmangle_property_name_ex(const zend_string *name, const char **class_name, const char **prop_name, size_t *prop_len);
#define ZEND_FUNCTION_DTOR zend_function_dtor
#define ZEND_CLASS_DTOR destroy_zend_class
@@ -648,21 +642,28 @@ int zend_add_literal(zend_op_array *op_array, zval *zv TSRMLS_DC);
#define ZEND_SEND_BY_REF 1
#define ZEND_SEND_PREFER_REF 2
#define CHECK_ARG_SEND_TYPE(zf, arg_num, m) \
(EXPECTED((zf)->common.arg_info != NULL) && \
(EXPECTED(arg_num <= (zf)->common.num_args) \
? ((zf)->common.arg_info[arg_num-1].pass_by_reference & (m)) \
: (UNEXPECTED((zf)->common.fn_flags & ZEND_ACC_VARIADIC) != 0) && \
((zf)->common.arg_info[(zf)->common.num_args-1].pass_by_reference & (m))))
static zend_always_inline int zend_check_arg_send_type(const zend_function *zf, uint32_t arg_num, uint32_t mask)
{
if (UNEXPECTED(zf->common.arg_info == NULL)) {
return 0;
}
if (UNEXPECTED(arg_num > zf->common.num_args)) {
if (EXPECTED((zf->common.fn_flags & ZEND_ACC_VARIADIC) == 0)) {
return 0;
}
arg_num = zf->common.num_args;
}
return UNEXPECTED((zf->common.arg_info[arg_num-1].pass_by_reference & mask) != 0);
}
#define ARG_MUST_BE_SENT_BY_REF(zf, arg_num) \
CHECK_ARG_SEND_TYPE(zf, arg_num, ZEND_SEND_BY_REF)
zend_check_arg_send_type(zf, arg_num, ZEND_SEND_BY_REF)
#define ARG_SHOULD_BE_SENT_BY_REF(zf, arg_num) \
CHECK_ARG_SEND_TYPE(zf, arg_num, ZEND_SEND_BY_REF|ZEND_SEND_PREFER_REF)
zend_check_arg_send_type(zf, arg_num, ZEND_SEND_BY_REF|ZEND_SEND_PREFER_REF)
#define ARG_MAY_BE_SENT_BY_REF(zf, arg_num) \
CHECK_ARG_SEND_TYPE(zf, arg_num, ZEND_SEND_PREFER_REF)
zend_check_arg_send_type(zf, arg_num, ZEND_SEND_PREFER_REF)
#define ZEND_RETURN_VAL 0
#define ZEND_RETURN_REF 1

View File

@@ -246,7 +246,7 @@ static zend_constant *zend_get_special_constant(const char *name, uint name_len
if ((c = zend_hash_find_ptr(EG(zend_constants), const_name)) == NULL) {
c = emalloc(sizeof(zend_constant));
memset(c, 0, sizeof(zend_constant));
ZVAL_STR(&c->value, zend_string_copy(EG(scope)->name));
ZVAL_STR_COPY(&c->value, EG(scope)->name);
zend_hash_add_ptr(EG(zend_constants), const_name, c);
}
zend_string_release(const_name);

View File

@@ -362,7 +362,7 @@ ZEND_METHOD(error_exception, getSeverity)
#define TRACE_ARG_APPEND(vallen) do { \
int len = str->len; \
size_t len = str->len; \
str = zend_string_realloc(str, len + vallen, 0); \
memmove(str->val + len - l_added + 1 + vallen, str->val + len - l_added + 1, l_added); \
} while (0)
@@ -620,10 +620,10 @@ ZEND_METHOD(exception, getPrevious)
RETURN_ZVAL(previous, 1, 0);
} /* }}} */
int zend_spprintf(char **message, int max_len, const char *format, ...) /* {{{ */
size_t zend_spprintf(char **message, size_t max_len, const char *format, ...) /* {{{ */
{
va_list arg;
int len;
size_t len;
va_start(arg, format);
len = zend_vspprintf(message, max_len, format, arg);
@@ -632,7 +632,7 @@ int zend_spprintf(char **message, int max_len, const char *format, ...) /* {{{ *
}
/* }}} */
zend_string *zend_strpprintf(int max_len, const char *format, ...) /* {{{ */
zend_string *zend_strpprintf(size_t max_len, const char *format, ...) /* {{{ */
{
va_list arg;
zend_string *str;

View File

@@ -53,8 +53,8 @@ extern ZEND_API void (*zend_throw_exception_hook)(zval *ex TSRMLS_DC);
ZEND_API void zend_exception_error(zend_object *exception, int severity TSRMLS_DC);
/* do not export, in php it's available thru spprintf directly */
int zend_spprintf(char **message, int max_len, const char *format, ...);
zend_string *zend_strpprintf(int max_len, const char *format, ...);
size_t zend_spprintf(char **message, size_t max_len, const char *format, ...);
zend_string *zend_strpprintf(size_t max_len, const char *format, ...);
END_EXTERN_C()

View File

@@ -38,6 +38,7 @@
#include "zend_generators.h"
#include "zend_vm.h"
#include "zend_dtrace.h"
#include "zend_inheritance.h"
/* Virtual current working directory support */
#include "zend_virtual_cwd.h"
@@ -83,7 +84,6 @@ static const zend_internal_function zend_pass_function = {
#undef zval_ptr_dtor
#define zval_ptr_dtor(zv) i_zval_ptr_dtor(zv ZEND_FILE_LINE_CC TSRMLS_CC)
#define zval_ptr_dtor_nogc(zv) i_zval_ptr_dtor_nogc(zv ZEND_FILE_LINE_CC TSRMLS_CC)
#define PZVAL_LOCK(z) if (Z_REFCOUNTED_P(z)) Z_ADDREF_P((z))
#define SELECTIVE_PZVAL_LOCK(pzv, opline) if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(pzv); }
@@ -211,11 +211,6 @@ static zend_always_inline zval *_get_zval_cv_lookup_BP_VAR_UNSET(zval *ptr, uint
return &EG(uninitialized_zval);
}
static zend_always_inline zval *_get_zval_cv_lookup_BP_VAR_IS(zval *ptr, uint32_t var, const zend_execute_data *execute_data TSRMLS_DC)
{
return &EG(uninitialized_zval);
}
static zend_always_inline zval *_get_zval_cv_lookup_BP_VAR_RW(zval *ptr, uint32_t var, const zend_execute_data *execute_data TSRMLS_DC)
{
zend_string *cv = CV_DEF_OF(EX_VAR_TO_NUM(var));
@@ -298,9 +293,6 @@ static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_IS(const zend_execute_da
{
zval *ret = EX_VAR(var);
if (Z_TYPE_P(ret) == IS_UNDEF) {
return _get_zval_cv_lookup_BP_VAR_IS(ret, var, execute_data TSRMLS_CC);
}
return ret;
}
@@ -308,9 +300,6 @@ static zend_always_inline zval *_get_zval_ptr_cv_deref_BP_VAR_IS(const zend_exec
{
zval *ret = EX_VAR(var);
if (Z_TYPE_P(ret) == IS_UNDEF) {
return _get_zval_cv_lookup_BP_VAR_IS(ret, var, execute_data TSRMLS_CC);
}
ZVAL_DEREF(ret);
return ret;
}
@@ -637,6 +626,7 @@ static inline int zend_verify_missing_arg_type(zend_function *zf, uint32_t arg_n
need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, "none", "", NULL TSRMLS_CC);
return 0;
} else if (cur_arg_info->type_hint) {
if (cur_arg_info->type_hint == IS_ARRAY) {
zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be of the type array", "", "none", "", NULL TSRMLS_CC);
@@ -647,8 +637,9 @@ static inline int zend_verify_missing_arg_type(zend_function *zf, uint32_t arg_n
zend_error(E_ERROR, "Unknown typehint");
#endif
}
return 0;
}
return 0;
return 1;
}
static void zend_verify_missing_arg(zend_execute_data *execute_data, uint32_t arg_num TSRMLS_DC)
@@ -756,17 +747,12 @@ static inline void zend_assign_to_object(zval *retval, zval *object_ptr, zval *p
FREE_OP_IF_VAR(free_value);
}
static void zend_assign_to_string_offset(zval *str_offset, zval *value, int value_type, zval *result TSRMLS_DC)
static void zend_assign_to_string_offset(zval *str, zend_long offset, zval *value, int value_type, zval *result TSRMLS_DC)
{
zval *str = Z_STR_OFFSET_STR_P(str_offset);
/* XXX String offset is uint32_t in _zval_struct, so can address only 2^32+1 space.
To make the offset get over that barier, we need to make str_offset size_t and that
would grow zval size by 8 bytes (currently from 16 to 24) on 64 bit build. */
uint32_t offset = Z_STR_OFFSET_IDX_P(str_offset);
zend_string *old_str;
if ((int)offset < 0) {
zend_error(E_WARNING, "Illegal string offset: %d", offset);
if (offset < 0) {
zend_error(E_WARNING, "Illegal string offset: " ZEND_LONG_FMT, offset);
zend_string_release(Z_STR_P(str));
if (result) {
ZVAL_NULL(result);
@@ -775,13 +761,13 @@ static void zend_assign_to_string_offset(zval *str_offset, zval *value, int valu
}
old_str = Z_STR_P(str);
if (offset >= Z_STRLEN_P(str)) {
int old_len = Z_STRLEN_P(str);
if ((size_t)offset >= Z_STRLEN_P(str)) {
zend_long old_len = Z_STRLEN_P(str);
Z_STR_P(str) = zend_string_realloc(Z_STR_P(str), offset + 1, 0);
Z_TYPE_INFO_P(str) = IS_STRING_EX;
memset(Z_STRVAL_P(str) + old_len, ' ', offset - old_len);
Z_STRVAL_P(str)[offset+1] = 0;
} else if (IS_INTERNED(Z_STR_P(str))) {
} else if (!Z_REFCOUNTED_P(str)) {
Z_STR_P(str) = zend_string_init(Z_STRVAL_P(str), Z_STRLEN_P(str), 0);
Z_TYPE_INFO_P(str) = IS_STRING_EX;
}
@@ -817,144 +803,61 @@ static void zend_assign_to_string_offset(zval *str_offset, zval *value, int valu
}
}
static inline zval* zend_assign_tmp_to_variable(zval *variable_ptr, zval *value TSRMLS_DC)
static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval *value, zend_uchar value_type TSRMLS_DC)
{
ZVAL_DEREF(variable_ptr);
do {
if (UNEXPECTED(Z_REFCOUNTED_P(variable_ptr))) {
zend_refcounted *garbage;
if (UNEXPECTED(Z_REFCOUNTED_P(variable_ptr))) {
zend_refcounted *garbage;
if (Z_TYPE_P(variable_ptr) == IS_OBJECT &&
UNEXPECTED(Z_OBJ_HANDLER_P(variable_ptr, set) != NULL)) {
Z_OBJ_HANDLER_P(variable_ptr, set)(variable_ptr, value TSRMLS_CC);
return variable_ptr;
}
garbage = Z_COUNTED_P(variable_ptr);
if (UNEXPECTED(GC_REFCOUNT(garbage) > 1)) {
/* we need to split */
GC_REFCOUNT(garbage)--;
/* optimized version of GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr) */
if ((Z_COLLECTABLE_P(variable_ptr)) &&
UNEXPECTED(!GC_INFO(garbage))) {
gc_possible_root(garbage TSRMLS_CC);
if (Z_ISREF_P(variable_ptr)) {
variable_ptr = Z_REFVAL_P(variable_ptr);
if (EXPECTED(!Z_REFCOUNTED_P(variable_ptr))) {
break;
}
}
} else {
ZVAL_COPY_VALUE(variable_ptr, value);
_zval_dtor_func(garbage ZEND_FILE_LINE_CC);
return variable_ptr;
}
}
ZVAL_COPY_VALUE(variable_ptr, value);
return variable_ptr;
}
static inline zval* zend_assign_const_to_variable(zval *variable_ptr, zval *value TSRMLS_DC)
{
ZVAL_DEREF(variable_ptr);
if (UNEXPECTED(Z_REFCOUNTED_P(variable_ptr))) {
zend_refcounted *garbage;
if (Z_TYPE_P(variable_ptr) == IS_OBJECT &&
UNEXPECTED(Z_OBJ_HANDLER_P(variable_ptr, set) != NULL)) {
Z_OBJ_HANDLER_P(variable_ptr, set)(variable_ptr, value TSRMLS_CC);
return variable_ptr;
}
garbage = Z_COUNTED_P(variable_ptr);
if (UNEXPECTED(GC_REFCOUNT(garbage) > 1)) {
/* we need to split */
GC_REFCOUNT(garbage)--;
/* optimized version of GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr) */
if (Z_COLLECTABLE_P(variable_ptr) &&
UNEXPECTED(!GC_INFO(garbage))) {
gc_possible_root(garbage TSRMLS_CC);
if (Z_TYPE_P(variable_ptr) == IS_OBJECT &&
UNEXPECTED(Z_OBJ_HANDLER_P(variable_ptr, set) != NULL)) {
Z_OBJ_HANDLER_P(variable_ptr, set)(variable_ptr, value TSRMLS_CC);
return variable_ptr;
}
} else {
ZVAL_COPY_VALUE(variable_ptr, value);
/* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */
if (UNEXPECTED(Z_OPT_COPYABLE_P(variable_ptr))) {
zval_copy_ctor_func(variable_ptr);
if ((value_type & (IS_VAR|IS_CV)) && variable_ptr == value) {
return variable_ptr;
}
_zval_dtor_func(garbage ZEND_FILE_LINE_CC);
return variable_ptr;
}
}
ZVAL_COPY_VALUE(variable_ptr, value);
/* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */
if (UNEXPECTED(Z_OPT_COPYABLE_P(variable_ptr))) {
zval_copy_ctor_func(variable_ptr);
}
return variable_ptr;
}
static inline zval* zend_assign_to_variable(zval *variable_ptr, zval *value TSRMLS_DC)
{
zend_refcounted *garbage;
if (EXPECTED(!Z_REFCOUNTED_P(variable_ptr))) {
goto assign_simple;
} else if (UNEXPECTED(variable_ptr == value)) {
return variable_ptr;
}
if (Z_ISREF_P(variable_ptr)) {
variable_ptr = Z_REFVAL_P(variable_ptr);
if (EXPECTED(!Z_REFCOUNTED_P(variable_ptr))) {
goto assign_simple;
} else if (UNEXPECTED(variable_ptr == value)) {
return variable_ptr;
}
}
if (Z_TYPE_P(variable_ptr) == IS_OBJECT &&
UNEXPECTED(Z_OBJ_HANDLER_P(variable_ptr, set) != NULL)) {
Z_OBJ_HANDLER_P(variable_ptr, set)(variable_ptr, value TSRMLS_CC);
} else {
if (Z_REFCOUNT_P(variable_ptr)==1) {
garbage = Z_COUNTED_P(variable_ptr);
if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
if (EXPECTED(!Z_ISREF_P(value))) {
Z_ADDREF_P(value);
} else {
if (Z_REFCOUNT_P(value) == 1) {
ZVAL_UNREF(value);
} else {
value = Z_REFVAL_P(value);
if (GC_REFCOUNT(garbage) == 1) {
ZVAL_COPY_VALUE(variable_ptr, value);
if (value_type == IS_CONST) {
/* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */
if (UNEXPECTED(Z_OPT_COPYABLE_P(variable_ptr))) {
zval_copy_ctor_func(variable_ptr);
}
if (Z_REFCOUNTED_P(value)) {
if (UNEXPECTED(variable_ptr == value)) {
return variable_ptr;
}
Z_ADDREF_P(value);
} else if (value_type != IS_TMP_VAR) {
if (UNEXPECTED(Z_OPT_REFCOUNTED_P(variable_ptr))) {
Z_ADDREF_P(variable_ptr);
}
}
}
ZVAL_COPY_VALUE(variable_ptr, value);
_zval_dtor_func(garbage ZEND_FILE_LINE_CC);
} else { /* we need to split */
Z_DELREF_P(variable_ptr);
GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr);
assign_simple:
if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
if (EXPECTED(!Z_ISREF_P(value))) {
Z_ADDREF_P(value);
} else {
if (Z_REFCOUNT_P(value) == 1) {
ZVAL_UNREF(value);
} else {
value = Z_REFVAL_P(value);
}
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
_zval_dtor_func(garbage ZEND_FILE_LINE_CC);
return variable_ptr;
} else { /* we need to split */
GC_REFCOUNT(garbage)--;
/* optimized version of GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr) */
if ((Z_COLLECTABLE_P(variable_ptr)) &&
UNEXPECTED(!GC_INFO(garbage))) {
gc_possible_root(garbage TSRMLS_CC);
}
}
ZVAL_COPY_VALUE(variable_ptr, value);
}
} while (0);
ZVAL_COPY_VALUE(variable_ptr, value);
if (value_type == IS_CONST) {
/* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */
if (UNEXPECTED(Z_OPT_COPYABLE_P(variable_ptr))) {
zval_copy_ctor_func(variable_ptr);
}
} else if (value_type != IS_TMP_VAR) {
if (UNEXPECTED(Z_OPT_REFCOUNTED_P(variable_ptr))) {
Z_ADDREF_P(variable_ptr);
}
}
return variable_ptr;
@@ -1107,7 +1010,7 @@ str_index:
return retval;
}
static zend_always_inline void zend_fetch_dimension_address(zval *result, zval *container_ptr, zval *dim, int dim_type, int type, int is_ref TSRMLS_DC)
static zend_always_inline zval *zend_fetch_dimension_address(zval *result, zval *container_ptr, zval *dim, int dim_type, int type, int is_ref, int allow_str_offset TSRMLS_DC)
{
zval *retval;
zval *container = container_ptr;
@@ -1142,14 +1045,11 @@ convert_to_array:
zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0);
goto fetch_from_array;
}
if (dim == NULL) {
zend_error_noreturn(E_ERROR, "[] operator not supported for strings");
}
if (type != BP_VAR_UNSET) {
SEPARATE_STRING(container);
}
if (UNEXPECTED(Z_TYPE_P(dim) != IS_LONG)) {
switch(Z_TYPE_P(dim)) {
case IS_STRING:
@@ -1176,8 +1076,19 @@ convert_to_array:
offset = Z_LVAL_P(dim);
}
if (!IS_INTERNED(Z_STR_P(container))) zend_string_addref(Z_STR_P(container));
ZVAL_STR_OFFSET(result, container, offset);
if (allow_str_offset) {
if (Z_REFCOUNTED_P(container)) {
if (Z_REFCOUNT_P(container) > 1) {
Z_DELREF_P(container);
zval_copy_ctor_func(container);
}
Z_ADDREF_P(container);
}
ZVAL_LONG(result, offset);
return container; /* assignment to string offset */
} else {
ZVAL_INDIRECT(result, NULL); /* wrong string offset */
}
} else if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (!Z_OBJ_HT_P(container)->read_dimension) {
zend_error_noreturn(E_ERROR, "Cannot use object as array");
@@ -1242,26 +1153,32 @@ convert_to_array:
ZVAL_INDIRECT(result, &EG(error_zval));
}
}
return NULL; /* not an assignment to string offset */
}
static zend_never_inline void zend_fetch_dimension_address_W(zval *result, zval *container_ptr, zval *dim, int dim_type TSRMLS_DC)
{
zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_W, 0 TSRMLS_CC);
zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_W, 0, 0 TSRMLS_CC);
}
static zend_never_inline zval *zend_fetch_dimension_address_W_str(zval *result, zval *container_ptr, zval *dim, int dim_type TSRMLS_DC)
{
return zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_W, 0, 1 TSRMLS_CC);
}
static zend_never_inline void zend_fetch_dimension_address_W_ref(zval *result, zval *container_ptr, zval *dim, int dim_type TSRMLS_DC)
{
zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_W, 1 TSRMLS_CC);
zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_W, 1, 0 TSRMLS_CC);
}
static zend_never_inline void zend_fetch_dimension_address_RW(zval *result, zval *container_ptr, zval *dim, int dim_type TSRMLS_DC)
{
zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_RW, 0 TSRMLS_CC);
zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_RW, 0, 0 TSRMLS_CC);
}
static zend_never_inline void zend_fetch_dimension_address_UNSET(zval *result, zval *container_ptr, zval *dim, int dim_type TSRMLS_DC)
{
zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_UNSET, 0 TSRMLS_CC);
zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_UNSET, 0, 0 TSRMLS_CC);
}
static zend_always_inline void zend_fetch_dimension_address_read(zval *result, zval *container, zval *dim, int dim_type, int type TSRMLS_DC)
@@ -1304,9 +1221,9 @@ static zend_always_inline void zend_fetch_dimension_address_read(zval *result, z
offset = Z_LVAL_P(dim);
}
if (UNEXPECTED(offset < 0) || UNEXPECTED(Z_STRLEN_P(container) <= offset)) {
if (UNEXPECTED(offset < 0) || UNEXPECTED(Z_STRLEN_P(container) <= (size_t)offset)) {
if (type != BP_VAR_IS) {
zend_error(E_NOTICE, "Uninitialized string offset: %ld", offset);
zend_error(E_NOTICE, "Uninitialized string offset: %pd", offset);
}
ZVAL_EMPTY_STRING(result);
} else {
@@ -1546,49 +1463,59 @@ void zend_free_compiled_variables(zend_execute_data *execute_data TSRMLS_DC) /*
static zend_always_inline void i_init_func_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value, vm_frame_kind frame_kind TSRMLS_DC) /* {{{ */
{
uint32_t first_extra_arg;
uint32_t first_extra_arg, num_args;
ZEND_ASSERT(EX(func) == (zend_function*)op_array);
ZEND_ASSERT(EX(object) == Z_OBJ(EG(This)));
EX(return_value) = return_value;
EX(frame_kind) = frame_kind;
ZVAL_UNDEF(&EX(old_error_reporting));
EX(delayed_exception) = NULL;
EX(call) = NULL;
EX(opline) = op_array->opcodes;
if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
/* Skip useless ZEND_RECV opcodes */
EX(opline) += MIN(EX(num_args), op_array->required_num_args);
}
EX(call) = NULL;
EX(frame_kind) = frame_kind;
EX(return_value) = return_value;
EX(scope) = EG(scope);
EX(delayed_exception) = NULL;
ZVAL_UNDEF(&EX(old_error_reporting));
/* Handle arguments */
first_extra_arg = op_array->num_args;
if (UNEXPECTED((op_array->fn_flags & ZEND_ACC_VARIADIC) != 0)) {
first_extra_arg--;
}
if (UNEXPECTED(EX(num_args) > first_extra_arg)) {
/* move extra args into separate array after all CV and TMP vars */
zval *extra_args = EX_VAR_NUM(op_array->last_var + op_array->T);
num_args = EX(num_args);
if (UNEXPECTED(num_args > first_extra_arg)) {
zval *end, *src, *dst;
memmove(extra_args, EX_VAR_NUM(first_extra_arg), sizeof(zval) * (EX(num_args) - first_extra_arg));
if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
/* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
EX(opline) += first_extra_arg;
}
/* move extra args into separate array after all CV and TMP vars */
end = EX_VAR_NUM(first_extra_arg - 1);
src = end + (num_args - first_extra_arg);
dst = src + (op_array->last_var + op_array->T - first_extra_arg);
if (EXPECTED(src != dst)) {
do {
ZVAL_COPY_VALUE(dst, src);
ZVAL_UNDEF(src);
src--;
dst--;
} while (src != end);
}
} else if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
/* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
EX(opline) += num_args;
}
do {
/* Initialize CV variables (skip arguments) */
int num_args = MIN(op_array->num_args, EX(num_args));
/* Initialize CV variables (skip arguments) */
if (EXPECTED(num_args < op_array->last_var)) {
zval *var = EX_VAR_NUM(num_args);
zval *end = EX_VAR_NUM(op_array->last_var);
if (EXPECTED(num_args < op_array->last_var)) {
zval *var = EX_VAR_NUM(num_args);
zval *end = EX_VAR_NUM(op_array->last_var);
do {
ZVAL_UNDEF(var);
var++;
} while (var != end);
}
} while (0);
do {
ZVAL_UNDEF(var);
var++;
} while (var != end);
}
if (op_array->this_var != -1 && EX(object)) {
ZVAL_OBJ(EX_VAR(op_array->this_var), EX(object));
@@ -1596,11 +1523,7 @@ static zend_always_inline void i_init_func_execute_data(zend_execute_data *execu
}
if (!op_array->run_time_cache && op_array->last_cache_slot) {
if (op_array->function_name) {
op_array->run_time_cache = zend_arena_calloc(&CG(arena), op_array->last_cache_slot, sizeof(void*));
} else {
op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*));
}
op_array->run_time_cache = zend_arena_calloc(&CG(arena), op_array->last_cache_slot, sizeof(void*));
}
EX(run_time_cache) = op_array->run_time_cache;
@@ -1613,23 +1536,18 @@ static zend_always_inline void i_init_code_execute_data(zend_execute_data *execu
ZEND_ASSERT(EX(func) == (zend_function*)op_array);
ZEND_ASSERT(EX(object) == Z_OBJ(EG(This)));
EX(return_value) = return_value;
EX(frame_kind) = frame_kind;
ZVAL_UNDEF(&EX(old_error_reporting));
EX(delayed_exception) = NULL;
EX(call) = NULL;
EX(opline) = op_array->opcodes;
EX(call) = NULL;
EX(frame_kind) = frame_kind;
EX(return_value) = return_value;
EX(scope) = EG(scope);
EX(delayed_exception) = NULL;
ZVAL_UNDEF(&EX(old_error_reporting));
zend_attach_symbol_table(execute_data);
if (!op_array->run_time_cache && op_array->last_cache_slot) {
if (op_array->function_name) {
op_array->run_time_cache = zend_arena_calloc(&CG(arena), op_array->last_cache_slot, sizeof(void*));
} else {
op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*));
}
op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*));
}
EX(run_time_cache) = op_array->run_time_cache;
@@ -1642,44 +1560,60 @@ static zend_always_inline void i_init_execute_data(zend_execute_data *execute_da
ZEND_ASSERT(EX(func) == (zend_function*)op_array);
ZEND_ASSERT(EX(object) == Z_OBJ(EG(This)));
EX(return_value) = return_value;
EX(frame_kind) = frame_kind;
ZVAL_UNDEF(&EX(old_error_reporting));
EX(delayed_exception) = NULL;
EX(call) = NULL;
EX(opline) = op_array->opcodes;
EX(call) = NULL;
EX(frame_kind) = frame_kind;
EX(return_value) = return_value;
EX(scope) = EG(scope);
EX(delayed_exception) = NULL;
ZVAL_UNDEF(&EX(old_error_reporting));
if (UNEXPECTED(EX(symbol_table) != NULL)) {
zend_attach_symbol_table(execute_data);
} else {
uint32_t first_extra_arg = op_array->num_args;
uint32_t first_extra_arg, num_args;
/* Handle arguments */
first_extra_arg = op_array->num_args;
if (UNEXPECTED((op_array->fn_flags & ZEND_ACC_VARIADIC) != 0)) {
first_extra_arg--;
}
if (UNEXPECTED(EX(num_args) > first_extra_arg)) {
/* move extra args into separate array after all CV and TMP vars */
zval *extra_args = EX_VAR_NUM(op_array->last_var + op_array->T);
num_args = EX(num_args);
if (UNEXPECTED(num_args > first_extra_arg)) {
zval *end, *src, *dst;
memmove(extra_args, EX_VAR_NUM(first_extra_arg), sizeof(zval) * (EX(num_args) - first_extra_arg));
if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
/* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
EX(opline) += first_extra_arg;
}
/* move extra args into separate array after all CV and TMP vars */
end = EX_VAR_NUM(first_extra_arg - 1);
src = end + (num_args - first_extra_arg);
dst = src + (op_array->last_var + op_array->T - first_extra_arg);
if (EXPECTED(src != dst)) {
do {
ZVAL_COPY_VALUE(dst, src);
ZVAL_UNDEF(src);
src--;
dst--;
} while (src != end);
}
} else if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
/* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
EX(opline) += num_args;
}
do {
/* Initialize CV variables (skip arguments) */
int num_args = MIN(op_array->num_args, EX(num_args));
/* Initialize CV variables (skip arguments) */
if (EXPECTED(num_args < op_array->last_var)) {
zval *var = EX_VAR_NUM(num_args);
zval *end = EX_VAR_NUM(op_array->last_var);
if (EXPECTED(num_args < op_array->last_var)) {
zval *var = EX_VAR_NUM(num_args);
zval *end = EX_VAR_NUM(op_array->last_var);
do {
ZVAL_UNDEF(var);
var++;
} while (var != end);
}
} while (0);
do {
ZVAL_UNDEF(var);
var++;
} while (var != end);
}
if (op_array->this_var != -1 && EX(object)) {
ZVAL_OBJ(EX_VAR(op_array->this_var), EX(object));
@@ -1732,7 +1666,7 @@ ZEND_API zend_execute_data *zend_create_generator_execute_data(zend_execute_data
if (num_args > 0) {
zval *arg_src = ZEND_CALL_ARG(call, 1);
zval *arg_dst = ZEND_CALL_ARG(execute_data, 1);
int i;
uint32_t i;
for (i = 0; i < num_args; i++) {
ZVAL_COPY_VALUE(arg_dst + i, arg_src + i);

View File

@@ -56,23 +56,13 @@ static zend_always_inline void i_zval_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC
if (Z_REFCOUNTED_P(zval_ptr)) {
if (!Z_DELREF_P(zval_ptr)) {
ZEND_ASSERT(zval_ptr != &EG(uninitialized_zval));
_zval_dtor_func_for_ptr(Z_COUNTED_P(zval_ptr) ZEND_FILE_LINE_CC);
_zval_dtor_func_for_ptr(Z_COUNTED_P(zval_ptr) ZEND_FILE_LINE_RELAY_CC);
} else {
GC_ZVAL_CHECK_POSSIBLE_ROOT(zval_ptr);
}
}
}
static zend_always_inline void i_zval_ptr_dtor_nogc(zval *zval_ptr ZEND_FILE_LINE_DC TSRMLS_DC)
{
if (Z_REFCOUNTED_P(zval_ptr)) {
if (!Z_DELREF_P(zval_ptr)) {
ZEND_ASSERT(zval_ptr != &EG(uninitialized_zval));
_zval_dtor_func_for_ptr(Z_COUNTED_P(zval_ptr) ZEND_FILE_LINE_CC);
}
}
}
static zend_always_inline int i_zend_is_true(zval *op TSRMLS_DC)
{
int result;
@@ -196,9 +186,9 @@ static zend_always_inline void zend_vm_stack_destroy(TSRMLS_D)
}
}
static zend_always_inline void zend_vm_stack_extend(int count TSRMLS_DC)
static zend_always_inline void zend_vm_stack_extend(uint32_t count TSRMLS_DC)
{
int size = count * ZEND_MM_ALIGNED_SIZE(sizeof(zval));
uint32_t size = count * ZEND_MM_ALIGNED_SIZE(sizeof(zval));
zend_vm_stack p = zend_vm_stack_new_page(
(size >= (ZEND_VM_STACK_PAGE_SIZE - ZEND_VM_STACK_HEADER_SLOT) * ZEND_MM_ALIGNED_SIZE(sizeof(zval))) ?
(size + ((ZEND_VM_STACK_HEADER_SLOT + ZEND_VM_STACK_PAGE_SIZE) * ZEND_MM_ALIGNED_SIZE(sizeof(zval))) - 1) &
@@ -210,7 +200,7 @@ static zend_always_inline void zend_vm_stack_extend(int count TSRMLS_DC)
static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame(zend_function *func, uint32_t num_args, zend_uchar flags, zend_class_entry *called_scope, zend_object *object, zend_execute_data *prev TSRMLS_DC)
{
int used_stack = ZEND_CALL_FRAME_SLOT + num_args;
uint32_t used_stack = ZEND_CALL_FRAME_SLOT + num_args;
zend_execute_data *call;
if (ZEND_USER_CODE(func->type)) {
@@ -237,7 +227,7 @@ static zend_always_inline void zend_vm_stack_free_extra_args(zend_execute_data *
zval *p = end + (call->num_args - first_extra_arg);
do {
p--;
i_zval_ptr_dtor_nogc(p ZEND_FILE_LINE_CC TSRMLS_CC);
zval_ptr_dtor_nogc(p);
} while (p != end);
}
}
@@ -252,7 +242,7 @@ static zend_always_inline void zend_vm_stack_free_args(zend_execute_data *call T
do {
p--;
i_zval_ptr_dtor_nogc(p ZEND_FILE_LINE_CC TSRMLS_CC);
zval_ptr_dtor_nogc(p);
} while (p != end);
}
}

View File

@@ -42,7 +42,7 @@ ZEND_API void (*zend_execute_ex)(zend_execute_data *execute_data TSRMLS_DC);
ZEND_API void (*zend_execute_internal)(zend_execute_data *execute_data, zval *return_value TSRMLS_DC);
/* true globals */
ZEND_API const zend_fcall_info empty_fcall_info = { 0, NULL, {{0}, {{0}}, {0}}, NULL, NULL, 0, NULL, NULL, 0 };
ZEND_API const zend_fcall_info empty_fcall_info = { 0, NULL, {{0}, {{0}}, {0}}, NULL, NULL, NULL, NULL, 0, 0 };
ZEND_API const zend_fcall_info_cache empty_fcall_info_cache = { 0, NULL, NULL, NULL, NULL };
#ifdef ZEND_WIN32
@@ -110,7 +110,7 @@ static int clean_non_persistent_function(zval *zv TSRMLS_DC) /* {{{ */
}
/* }}} */
static int clean_non_persistent_function_full(zval *zv TSRMLS_DC) /* {{{ */
ZEND_API int clean_non_persistent_function_full(zval *zv TSRMLS_DC) /* {{{ */
{
zend_function *function = Z_PTR_P(zv);
return (function->type == ZEND_INTERNAL_FUNCTION) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE;
@@ -124,7 +124,7 @@ static int clean_non_persistent_class(zval *zv TSRMLS_DC) /* {{{ */
}
/* }}} */
static int clean_non_persistent_class_full(zval *zv TSRMLS_DC) /* {{{ */
ZEND_API int clean_non_persistent_class_full(zval *zv TSRMLS_DC) /* {{{ */
{
zend_class_entry *ce = Z_PTR_P(zv);
return (ce->type == ZEND_INTERNAL_CLASS) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE;
@@ -580,8 +580,8 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas
if (!inline_change) {
ZVAL_STRINGL(p, actual, actual_len);
} else {
Z_TYPE_INFO_P(p) = IS_INTERNED(Z_STR_P(p)) ?
IS_INTERNED_STRING_EX : IS_STRING_EX;
Z_TYPE_INFO_P(p) = Z_REFCOUNTED_P(p) ?
IS_STRING_EX : IS_INTERNED_STRING_EX;
if (save && save->val != actual) {
zend_string_release(save);
}
@@ -1011,12 +1011,12 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *k
if (name->val[0] == '\\') {
ZVAL_STRINGL(&args[0], name->val + 1, name->len - 1);
} else {
ZVAL_STR(&args[0], zend_string_copy(name));
ZVAL_STR_COPY(&args[0], name);
}
fcall_info.size = sizeof(fcall_info);
fcall_info.function_table = EG(function_table);
ZVAL_STR(&fcall_info.function_name, zend_string_copy(EG(autoload_func)->common.function_name));
ZVAL_STR_COPY(&fcall_info.function_name, EG(autoload_func)->common.function_name);
fcall_info.symbol_table = NULL;
fcall_info.retval = &local_retval;
fcall_info.param_count = 1;
@@ -1502,7 +1502,7 @@ ZEND_API int zend_delete_global_variable(zend_string *name TSRMLS_DC) /* {{{ */
ZEND_API zend_array *zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */
{
uint32_t i;
int i;
zend_execute_data *ex;
zend_array *symbol_table;

View File

@@ -195,7 +195,7 @@ void zend_shutdown_extensions(TSRMLS_D)
void zend_extension_dtor(zend_extension *extension)
{
#if ZEND_EXTENSIONS_SUPPORT && !ZEND_DEBUG
if (extension->handle) {
if (extension->handle && !getenv("ZEND_DONT_UNLOAD_MODULES")) {
DL_UNLOAD(extension->handle);
}
#endif

View File

@@ -99,6 +99,7 @@ ZEND_API void gc_reset(TSRMLS_D)
{
GC_G(gc_runs) = 0;
GC_G(collected) = 0;
GC_G(gc_full) = 0;
#if GC_BENCH
GC_G(root_buf_length) = 0;
@@ -185,14 +186,6 @@ ZEND_API void gc_remove_from_buffer(zend_refcounted *ref TSRMLS_DC)
{
gc_root_buffer *root;
if (UNEXPECTED(/*GC_ADDRESS(GC_INFO(ref)) &&*/
GC_GET_COLOR(GC_INFO(ref)) == GC_BLACK &&
GC_ADDRESS(GC_INFO(ref)) >= GC_G(last_unused) - GC_G(buf))) {
/* The given zval is a garbage that is going to be deleted by
* currently running GC */
return;
}
root = GC_G(buf) + GC_ADDRESS(GC_INFO(ref));
GC_BENCH_INC(zval_remove_from_buffer);
GC_REMOVE_FROM_ROOTS(root);
@@ -492,8 +485,11 @@ tail_call:
} else if (GC_G(first_unused) != GC_G(last_unused)) {
buf = GC_G(first_unused);
GC_G(first_unused)++;
} else {
/* TODO: find a perfect way to handle such case */
GC_G(gc_full) = 1;
}
/* TODO: what should we do if we don't have room ??? */
if (buf) {
buf->ref = ref;
buf->next = GC_G(roots).next;
@@ -609,6 +605,18 @@ static int gc_collect_roots(TSRMLS_D)
}
current = current->next;
}
if (GC_G(gc_full) == 1) {
current = GC_G(roots).next;
while (current != &GC_G(roots)) {
GC_SET_ADDRESS(GC_INFO(current->ref), 0);
GC_SET_BLACK(GC_INFO(current->ref));
current = current->next;
}
gc_reset(TSRMLS_C);
return 0;
}
/* relink remaining roots into list to free */
if (GC_G(roots).next != &GC_G(roots)) {
if (GC_G(to_free).next == &GC_G(to_free)) {

View File

@@ -83,6 +83,7 @@ typedef struct _gc_root_buffer {
typedef struct _zend_gc_globals {
zend_bool gc_enabled;
zend_bool gc_active;
zend_bool gc_full;
gc_root_buffer *buf; /* preallocated arrays of buffers */
gc_root_buffer roots; /* list of possible roots of cycles */

View File

@@ -254,7 +254,7 @@ struct _zend_ini_scanner_globals {
char *filename;
int lineno;
/* Modes are: ZEND_INI_SCANNER_NORMAL, ZEND_INI_SCANNER_RAW */
/* Modes are: ZEND_INI_SCANNER_NORMAL, ZEND_INI_SCANNER_RAW, ZEND_INI_SCANNER_TYPED */
int scanner_mode;
};

View File

@@ -97,9 +97,9 @@ static void zend_hash_do_resize(HashTable *ht);
static const uint32_t uninitialized_bucket = {INVALID_IDX};
ZEND_API void _zend_hash_init(HashTable *ht, uint nSize, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC)
ZEND_API void _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC)
{
uint i = 3;
uint32_t i = 3;
SET_INCONSISTENT(HT_OK);
@@ -137,7 +137,7 @@ static void zend_hash_packed_grow(HashTable *ht)
HANDLE_UNBLOCK_INTERRUPTIONS();
}
ZEND_API void zend_hash_real_init(HashTable *ht, int packed)
ZEND_API void zend_hash_real_init(HashTable *ht, zend_bool packed)
{
IS_CONSISTENT(ht);
@@ -163,7 +163,7 @@ ZEND_API void zend_hash_to_packed(HashTable *ht)
HANDLE_UNBLOCK_INTERRUPTIONS();
}
ZEND_API void _zend_hash_init_ex(HashTable *ht, uint nSize, dtor_func_t pDestructor, zend_bool persistent, zend_bool bApplyProtection ZEND_FILE_LINE_DC)
ZEND_API void _zend_hash_init_ex(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent, zend_bool bApplyProtection ZEND_FILE_LINE_DC)
{
_zend_hash_init(ht, nSize, pDestructor, persistent ZEND_FILE_LINE_CC);
if (!bApplyProtection) {
@@ -184,8 +184,8 @@ ZEND_API void zend_hash_set_apply_protection(HashTable *ht, zend_bool bApplyProt
static zend_always_inline Bucket *zend_hash_find_bucket(const HashTable *ht, zend_string *key)
{
zend_ulong h;
uint nIndex;
uint idx;
uint32_t nIndex;
uint32_t idx;
Bucket *p;
h = zend_string_hash_val(key);
@@ -205,10 +205,10 @@ static zend_always_inline Bucket *zend_hash_find_bucket(const HashTable *ht, zen
return NULL;
}
static zend_always_inline Bucket *zend_hash_str_find_bucket(const HashTable *ht, const char *str, int len, zend_ulong h)
static zend_always_inline Bucket *zend_hash_str_find_bucket(const HashTable *ht, const char *str, size_t len, zend_ulong h)
{
uint nIndex;
uint idx;
uint32_t nIndex;
uint32_t idx;
Bucket *p;
nIndex = h & ht->nTableMask;
@@ -229,8 +229,8 @@ static zend_always_inline Bucket *zend_hash_str_find_bucket(const HashTable *ht,
static zend_always_inline Bucket *zend_hash_index_find_bucket(const HashTable *ht, zend_ulong h)
{
uint nIndex;
uint idx;
uint32_t nIndex;
uint32_t idx;
Bucket *p;
nIndex = h & ht->nTableMask;
@@ -246,11 +246,11 @@ static zend_always_inline Bucket *zend_hash_index_find_bucket(const HashTable *h
return NULL;
}
static zend_always_inline zval *_zend_hash_add_or_update_i(HashTable *ht, zend_string *key, zval *pData, int flag ZEND_FILE_LINE_DC)
static zend_always_inline zval *_zend_hash_add_or_update_i(HashTable *ht, zend_string *key, zval *pData, uint32_t flag ZEND_FILE_LINE_DC)
{
zend_ulong h;
uint nIndex;
uint idx;
uint32_t nIndex;
uint32_t idx;
Bucket *p;
#ifdef ZEND_SIGNALS
TSRMLS_FETCH();
@@ -310,7 +310,7 @@ static zend_always_inline zval *_zend_hash_add_or_update_i(HashTable *ht, zend_s
return &p->val;
}
ZEND_API zval *_zend_hash_add_or_update(HashTable *ht, zend_string *key, zval *pData, int flag ZEND_FILE_LINE_DC)
ZEND_API zval *_zend_hash_add_or_update(HashTable *ht, zend_string *key, zval *pData, uint32_t flag ZEND_FILE_LINE_DC)
{
return _zend_hash_add_or_update_i(ht, key, pData, flag ZEND_FILE_LINE_RELAY_CC);
}
@@ -335,7 +335,7 @@ ZEND_API zval *_zend_hash_add_new(HashTable *ht, zend_string *key, zval *pData Z
return _zend_hash_add_or_update_i(ht, key, pData, HASH_ADD_NEW ZEND_FILE_LINE_RELAY_CC);
}
ZEND_API zval *_zend_hash_str_add_or_update(HashTable *ht, const char *str, int len, zval *pData, int flag ZEND_FILE_LINE_DC)
ZEND_API zval *_zend_hash_str_add_or_update(HashTable *ht, const char *str, size_t len, zval *pData, uint32_t flag ZEND_FILE_LINE_DC)
{
zend_string *key = zend_string_init(str, len, ht->u.flags & HASH_FLAG_PERSISTENT);
zval *ret = _zend_hash_add_or_update_i(ht, key, pData, flag ZEND_FILE_LINE_CC);
@@ -343,7 +343,7 @@ ZEND_API zval *_zend_hash_str_add_or_update(HashTable *ht, const char *str, int
return ret;
}
ZEND_API zval *_zend_hash_str_update(HashTable *ht, const char *str, int len, zval *pData ZEND_FILE_LINE_DC)
ZEND_API zval *_zend_hash_str_update(HashTable *ht, const char *str, size_t len, zval *pData ZEND_FILE_LINE_DC)
{
zend_string *key = zend_string_init(str, len, ht->u.flags & HASH_FLAG_PERSISTENT);
zval *ret = _zend_hash_add_or_update_i(ht, key, pData, HASH_UPDATE ZEND_FILE_LINE_CC);
@@ -351,7 +351,7 @@ ZEND_API zval *_zend_hash_str_update(HashTable *ht, const char *str, int len, zv
return ret;
}
ZEND_API zval *_zend_hash_str_update_ind(HashTable *ht, const char *str, int len, zval *pData ZEND_FILE_LINE_DC)
ZEND_API zval *_zend_hash_str_update_ind(HashTable *ht, const char *str, size_t len, zval *pData ZEND_FILE_LINE_DC)
{
zend_string *key = zend_string_init(str, len, ht->u.flags & HASH_FLAG_PERSISTENT);
zval *ret = _zend_hash_add_or_update_i(ht, key, pData, HASH_UPDATE | HASH_UPDATE_INDIRECT ZEND_FILE_LINE_CC);
@@ -359,7 +359,7 @@ ZEND_API zval *_zend_hash_str_update_ind(HashTable *ht, const char *str, int len
return ret;
}
ZEND_API zval *_zend_hash_str_add(HashTable *ht, const char *str, int len, zval *pData ZEND_FILE_LINE_DC)
ZEND_API zval *_zend_hash_str_add(HashTable *ht, const char *str, size_t len, zval *pData ZEND_FILE_LINE_DC)
{
zend_string *key = zend_string_init(str, len, ht->u.flags & HASH_FLAG_PERSISTENT);
zval *ret = _zend_hash_add_or_update_i(ht, key, pData, HASH_ADD ZEND_FILE_LINE_CC);
@@ -367,7 +367,7 @@ ZEND_API zval *_zend_hash_str_add(HashTable *ht, const char *str, int len, zval
return ret;
}
ZEND_API zval *_zend_hash_str_add_new(HashTable *ht, const char *str, int len, zval *pData ZEND_FILE_LINE_DC)
ZEND_API zval *_zend_hash_str_add_new(HashTable *ht, const char *str, size_t len, zval *pData ZEND_FILE_LINE_DC)
{
zend_string *key = zend_string_init(str, len, ht->u.flags & HASH_FLAG_PERSISTENT);
zval *ret = _zend_hash_add_or_update_i(ht, key, pData, HASH_ADD_NEW ZEND_FILE_LINE_CC);
@@ -393,7 +393,7 @@ ZEND_API zval *zend_hash_add_empty_element(HashTable *ht, zend_string *key)
return zend_hash_add(ht, key, &dummy);
}
ZEND_API zval *zend_hash_str_add_empty_element(HashTable *ht, const char *str, int len)
ZEND_API zval *zend_hash_str_add_empty_element(HashTable *ht, const char *str, size_t len)
{
zval dummy;
@@ -402,85 +402,80 @@ ZEND_API zval *zend_hash_str_add_empty_element(HashTable *ht, const char *str, i
return zend_hash_str_add(ht, str, len, &dummy);
}
static zend_always_inline zval *_zend_hash_index_update_or_next_insert_i(HashTable *ht, zend_ulong h, zval *pData, int flag ZEND_FILE_LINE_DC)
static zend_always_inline zval *_zend_hash_index_add_or_update_i(HashTable *ht, zend_ulong h, zval *pData, uint32_t flag ZEND_FILE_LINE_DC)
{
uint nIndex;
uint idx;
uint32_t nIndex;
uint32_t idx;
Bucket *p;
#ifdef ZEND_SIGNALS
TSRMLS_FETCH();
#endif
IS_CONSISTENT(ht);
if (flag & HASH_NEXT_INSERT) {
h = ht->nNextFreeElement;
}
CHECK_INIT(ht, h >= 0 && h < ht->nTableSize);
CHECK_INIT(ht, h < ht->nTableSize);
if (ht->u.flags & HASH_FLAG_PACKED) {
if (EXPECTED(h >= 0)) {
if (h < ht->nNumUsed) {
p = ht->arData + h;
if (Z_TYPE(p->val) != IS_UNDEF) {
if (flag & (HASH_NEXT_INSERT | HASH_ADD)) {
return NULL;
}
if (ht->pDestructor) {
ht->pDestructor(&p->val);
}
ZVAL_COPY_VALUE(&p->val, pData);
if ((zend_long)h >= (zend_long)ht->nNextFreeElement) {
ht->nNextFreeElement = h < ZEND_LONG_MAX ? h + 1 : ZEND_LONG_MAX;
}
return &p->val;
} else { /* we have to keep the order :( */
goto convert_to_hash;
if (h < ht->nNumUsed) {
p = ht->arData + h;
if (Z_TYPE(p->val) != IS_UNDEF) {
if (flag & HASH_ADD) {
return NULL;
}
} else if (EXPECTED(h < ht->nTableSize)) {
p = ht->arData + h;
} else if (h < ht->nTableSize * 2 &&
ht->nTableSize - ht->nNumOfElements < ht->nTableSize / 2) {
zend_hash_packed_grow(ht);
p = ht->arData + h;
} else {
goto convert_to_hash;
}
HANDLE_BLOCK_INTERRUPTIONS();
/* incremental initialization of empty Buckets */
if (h >= ht->nNumUsed) {
Bucket *q = ht->arData + ht->nNumUsed;
while (q != p) {
ZVAL_UNDEF(&q->val);
q++;
if (ht->pDestructor) {
ht->pDestructor(&p->val);
}
ht->nNumUsed = h + 1;
ZVAL_COPY_VALUE(&p->val, pData);
if ((zend_long)h >= (zend_long)ht->nNextFreeElement) {
ht->nNextFreeElement = h < ZEND_LONG_MAX ? h + 1 : ZEND_LONG_MAX;
}
return &p->val;
} else { /* we have to keep the order :( */
goto convert_to_hash;
}
ht->nNumOfElements++;
if (ht->nInternalPointer == INVALID_IDX) {
ht->nInternalPointer = h;
}
if ((zend_long)h >= (zend_long)ht->nNextFreeElement) {
ht->nNextFreeElement = h < ZEND_LONG_MAX ? h + 1 : ZEND_LONG_MAX;
}
p->h = h;
p->key = NULL;
ZVAL_COPY_VALUE(&p->val, pData);
Z_NEXT(p->val) = INVALID_IDX;
HANDLE_UNBLOCK_INTERRUPTIONS();
return &p->val;
} else if (EXPECTED(h < ht->nTableSize)) {
p = ht->arData + h;
} else if (h < ht->nTableSize * 2 &&
ht->nTableSize - ht->nNumOfElements < ht->nTableSize / 2) {
zend_hash_packed_grow(ht);
p = ht->arData + h;
} else {
convert_to_hash:
zend_hash_packed_to_hash(ht);
goto convert_to_hash;
}
HANDLE_BLOCK_INTERRUPTIONS();
/* incremental initialization of empty Buckets */
if (h >= ht->nNumUsed) {
Bucket *q = ht->arData + ht->nNumUsed;
while (q != p) {
ZVAL_UNDEF(&q->val);
q++;
}
ht->nNumUsed = h + 1;
}
ht->nNumOfElements++;
if (ht->nInternalPointer == INVALID_IDX) {
ht->nInternalPointer = h;
}
if ((zend_long)h >= (zend_long)ht->nNextFreeElement) {
ht->nNextFreeElement = h < ZEND_LONG_MAX ? h + 1 : ZEND_LONG_MAX;
}
p->h = h;
p->key = NULL;
ZVAL_COPY_VALUE(&p->val, pData);
Z_NEXT(p->val) = INVALID_IDX;
HANDLE_UNBLOCK_INTERRUPTIONS();
return &p->val;
convert_to_hash:
zend_hash_packed_to_hash(ht);
}
if ((flag & HASH_ADD_NEW) == 0) {
p = zend_hash_index_find_bucket(ht, h);
if (p) {
if (flag & (HASH_NEXT_INSERT | HASH_ADD)) {
if (flag & HASH_ADD) {
return NULL;
}
ZEND_ASSERT(&p->val != pData);
@@ -520,34 +515,34 @@ convert_to_hash:
return &p->val;
}
ZEND_API zval *_zend_hash_index_update_or_next_insert(HashTable *ht, zend_ulong h, zval *pData, int flag ZEND_FILE_LINE_DC)
ZEND_API zval *_zend_hash_index_add_or_update(HashTable *ht, zend_ulong h, zval *pData, uint32_t flag ZEND_FILE_LINE_DC)
{
return _zend_hash_index_update_or_next_insert_i(ht, h, pData, flag ZEND_FILE_LINE_RELAY_CC);
return _zend_hash_index_add_or_update_i(ht, h, pData, flag ZEND_FILE_LINE_RELAY_CC);
}
ZEND_API zval *_zend_hash_index_add(HashTable *ht, zend_ulong h, zval *pData ZEND_FILE_LINE_DC)
{
return _zend_hash_index_update_or_next_insert_i(ht, h, pData, HASH_ADD ZEND_FILE_LINE_RELAY_CC);
return _zend_hash_index_add_or_update_i(ht, h, pData, HASH_ADD ZEND_FILE_LINE_RELAY_CC);
}
ZEND_API zval *_zend_hash_index_add_new(HashTable *ht, zend_ulong h, zval *pData ZEND_FILE_LINE_DC)
{
return _zend_hash_index_update_or_next_insert_i(ht, h, pData, HASH_ADD | HASH_ADD_NEW ZEND_FILE_LINE_RELAY_CC);
return _zend_hash_index_add_or_update_i(ht, h, pData, HASH_ADD | HASH_ADD_NEW ZEND_FILE_LINE_RELAY_CC);
}
ZEND_API zval *_zend_hash_index_update(HashTable *ht, zend_ulong h, zval *pData ZEND_FILE_LINE_DC)
{
return _zend_hash_index_update_or_next_insert_i(ht, h, pData, HASH_UPDATE ZEND_FILE_LINE_RELAY_CC);
return _zend_hash_index_add_or_update_i(ht, h, pData, HASH_UPDATE ZEND_FILE_LINE_RELAY_CC);
}
ZEND_API zval *_zend_hash_next_index_insert(HashTable *ht, zval *pData ZEND_FILE_LINE_DC)
{
return _zend_hash_index_update_or_next_insert_i(ht, ht->nNextFreeElement, pData, HASH_NEXT_INSERT ZEND_FILE_LINE_RELAY_CC);
return _zend_hash_index_add_or_update_i(ht, ht->nNextFreeElement, pData, HASH_ADD ZEND_FILE_LINE_RELAY_CC);
}
ZEND_API zval *_zend_hash_next_index_insert_new(HashTable *ht, zval *pData ZEND_FILE_LINE_DC)
{
return _zend_hash_index_update_or_next_insert_i(ht, ht->nNextFreeElement, pData, HASH_NEXT_INSERT | HASH_ADD_NEW ZEND_FILE_LINE_RELAY_CC);
return _zend_hash_index_add_or_update_i(ht, ht->nNextFreeElement, pData, HASH_ADD | HASH_ADD_NEW ZEND_FILE_LINE_RELAY_CC);
}
static void zend_hash_do_resize(HashTable *ht)
@@ -576,7 +571,7 @@ static void zend_hash_do_resize(HashTable *ht)
ZEND_API int zend_hash_rehash(HashTable *ht)
{
Bucket *p;
uint nIndex, i, j;
uint32_t nIndex, i, j;
IS_CONSISTENT(ht);
@@ -606,7 +601,7 @@ ZEND_API int zend_hash_rehash(HashTable *ht)
return SUCCESS;
}
static zend_always_inline void _zend_hash_del_el_ex(HashTable *ht, uint idx, Bucket *p, Bucket *prev)
static zend_always_inline void _zend_hash_del_el_ex(HashTable *ht, uint32_t idx, Bucket *p, Bucket *prev)
{
if (!(ht->u.flags & HASH_FLAG_PACKED)) {
if (prev) {
@@ -646,21 +641,20 @@ static zend_always_inline void _zend_hash_del_el_ex(HashTable *ht, uint idx, Buc
}
}
static zend_always_inline void _zend_hash_del_el(HashTable *ht, uint idx, Bucket *p)
static zend_always_inline void _zend_hash_del_el(HashTable *ht, uint32_t idx, Bucket *p)
{
uint nIndex;
Bucket *prev = NULL;
if (!(ht->u.flags & HASH_FLAG_PACKED)) {
nIndex = p->h & ht->nTableMask;
idx = ht->arHash[nIndex];
if (p != ht->arData + idx) {
prev = ht->arData + idx;
while (ht->arData + Z_NEXT(prev->val) != p) {
idx = Z_NEXT(prev->val);
prev = ht->arData + idx;
uint32_t nIndex = p->h & ht->nTableMask;
uint32_t i = ht->arHash[nIndex];
if (i != idx) {
prev = ht->arData + i;
while (Z_NEXT(prev->val) != idx) {
i = Z_NEXT(prev->val);
prev = ht->arData + i;
}
idx = Z_NEXT(prev->val);
}
}
@@ -670,8 +664,8 @@ static zend_always_inline void _zend_hash_del_el(HashTable *ht, uint idx, Bucket
ZEND_API int zend_hash_del(HashTable *ht, zend_string *key)
{
zend_ulong h;
uint nIndex;
uint idx;
uint32_t nIndex;
uint32_t idx;
Bucket *p;
Bucket *prev = NULL;
#ifdef ZEND_SIGNALS
@@ -709,8 +703,8 @@ ZEND_API int zend_hash_del(HashTable *ht, zend_string *key)
ZEND_API int zend_hash_del_ind(HashTable *ht, zend_string *key)
{
zend_ulong h;
uint nIndex;
uint idx;
uint32_t nIndex;
uint32_t idx;
Bucket *p;
Bucket *prev = NULL;
#ifdef ZEND_SIGNALS
@@ -758,11 +752,11 @@ ZEND_API int zend_hash_del_ind(HashTable *ht, zend_string *key)
return FAILURE;
}
ZEND_API int zend_hash_str_del(HashTable *ht, const char *str, int len)
ZEND_API int zend_hash_str_del(HashTable *ht, const char *str, size_t len)
{
zend_ulong h;
uint nIndex;
uint idx;
uint32_t nIndex;
uint32_t idx;
Bucket *p;
Bucket *prev = NULL;
#ifdef ZEND_SIGNALS
@@ -809,11 +803,11 @@ ZEND_API int zend_hash_str_del(HashTable *ht, const char *str, int len)
return FAILURE;
}
ZEND_API int zend_hash_str_del_ind(HashTable *ht, const char *str, int len)
ZEND_API int zend_hash_str_del_ind(HashTable *ht, const char *str, size_t len)
{
zend_ulong h;
uint nIndex;
uint idx;
uint32_t nIndex;
uint32_t idx;
Bucket *p;
Bucket *prev = NULL;
#ifdef ZEND_SIGNALS
@@ -845,8 +839,8 @@ ZEND_API int zend_hash_str_del_ind(HashTable *ht, const char *str, int len)
ZEND_API int zend_hash_index_del(HashTable *ht, zend_ulong h)
{
uint nIndex;
uint idx;
uint32_t nIndex;
uint32_t idx;
Bucket *p;
Bucket *prev = NULL;
#ifdef ZEND_SIGNALS
@@ -856,7 +850,7 @@ ZEND_API int zend_hash_index_del(HashTable *ht, zend_ulong h)
IS_CONSISTENT(ht);
if (ht->u.flags & HASH_FLAG_PACKED) {
if (h >=0 && h < ht->nNumUsed) {
if (h < ht->nNumUsed) {
p = ht->arData + h;
if (Z_TYPE(p->val) != IS_UNDEF) {
HANDLE_BLOCK_INTERRUPTIONS();
@@ -934,7 +928,7 @@ ZEND_API void zend_hash_destroy(HashTable *ht)
ZEND_API void zend_hash_clean(HashTable *ht)
{
uint idx;
uint32_t idx;
Bucket *p;
IS_CONSISTENT(ht);
@@ -965,7 +959,7 @@ ZEND_API void zend_hash_clean(HashTable *ht)
* next bucket. The hash *may* be altered during that time, the
* returned value will still be valid.
*/
static void zend_hash_apply_deleter(HashTable *ht, uint idx, Bucket *p)
static void zend_hash_apply_deleter(HashTable *ht, uint32_t idx, Bucket *p)
{
#ifdef ZEND_SIGNALS
TSRMLS_FETCH();
@@ -979,7 +973,7 @@ static void zend_hash_apply_deleter(HashTable *ht, uint idx, Bucket *p)
ZEND_API void zend_hash_graceful_destroy(HashTable *ht)
{
uint idx;
uint32_t idx;
Bucket *p;
IS_CONSISTENT(ht);
@@ -998,7 +992,7 @@ ZEND_API void zend_hash_graceful_destroy(HashTable *ht)
ZEND_API void zend_hash_graceful_reverse_destroy(HashTable *ht)
{
uint idx;
uint32_t idx;
Bucket *p;
IS_CONSISTENT(ht);
@@ -1029,7 +1023,7 @@ ZEND_API void zend_hash_graceful_reverse_destroy(HashTable *ht)
ZEND_API void zend_hash_apply(HashTable *ht, apply_func_t apply_func TSRMLS_DC)
{
uint idx;
uint32_t idx;
Bucket *p;
int result;
@@ -1055,7 +1049,7 @@ ZEND_API void zend_hash_apply(HashTable *ht, apply_func_t apply_func TSRMLS_DC)
ZEND_API void zend_hash_apply_with_argument(HashTable *ht, apply_func_arg_t apply_func, void *argument TSRMLS_DC)
{
uint idx;
uint32_t idx;
Bucket *p;
int result;
@@ -1081,7 +1075,7 @@ ZEND_API void zend_hash_apply_with_argument(HashTable *ht, apply_func_arg_t appl
ZEND_API void zend_hash_apply_with_arguments(HashTable *ht TSRMLS_DC, apply_func_args_t apply_func, int num_args, ...)
{
uint idx;
uint32_t idx;
Bucket *p;
va_list args;
zend_hash_key hash_key;
@@ -1116,7 +1110,7 @@ ZEND_API void zend_hash_apply_with_arguments(HashTable *ht TSRMLS_DC, apply_func
ZEND_API void zend_hash_reverse_apply(HashTable *ht, apply_func_t apply_func TSRMLS_DC)
{
uint idx;
uint32_t idx;
Bucket *p;
int result;
@@ -1144,7 +1138,7 @@ ZEND_API void zend_hash_reverse_apply(HashTable *ht, apply_func_t apply_func TSR
ZEND_API void zend_hash_copy(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor)
{
uint idx;
uint32_t idx;
Bucket *p;
zval *new_entry, *data;
zend_bool setTargetPointer;
@@ -1189,8 +1183,8 @@ ZEND_API void zend_hash_copy(HashTable *target, HashTable *source, copy_ctor_fun
ZEND_API void zend_array_dup(HashTable *target, HashTable *source)
{
uint idx, target_idx;
uint nIndex;
uint32_t idx, target_idx;
uint32_t nIndex;
Bucket *p, *q;
zval *data;
@@ -1308,12 +1302,12 @@ ZEND_API void zend_array_dup(HashTable *target, HashTable *source)
}
ZEND_API void _zend_hash_merge(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, int overwrite ZEND_FILE_LINE_DC)
ZEND_API void _zend_hash_merge(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, zend_bool overwrite ZEND_FILE_LINE_DC)
{
uint idx;
uint32_t idx;
Bucket *p;
zval *t;
int mode = (overwrite?HASH_UPDATE:HASH_ADD);
uint32_t mode = (overwrite?HASH_UPDATE:HASH_ADD);
IS_CONSISTENT(source);
IS_CONSISTENT(target);
@@ -1357,7 +1351,7 @@ static zend_bool zend_hash_replace_checker_wrapper(HashTable *target, zval *sour
ZEND_API void zend_hash_merge_ex(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, merge_checker_func_t pMergeSource, void *pParam)
{
uint idx;
uint32_t idx;
Bucket *p;
zval *t;
@@ -1402,7 +1396,7 @@ ZEND_API zval *zend_hash_find(const HashTable *ht, zend_string *key)
return p ? &p->val : NULL;
}
ZEND_API zval *zend_hash_str_find(const HashTable *ht, const char *str, int len)
ZEND_API zval *zend_hash_str_find(const HashTable *ht, const char *str, size_t len)
{
zend_ulong h;
Bucket *p;
@@ -1418,7 +1412,7 @@ ZEND_API zval *zend_hash_str_find(const HashTable *ht, const char *str, int len)
return p ? &p->val : NULL;
}
ZEND_API int zend_hash_exists(const HashTable *ht, zend_string *key)
ZEND_API zend_bool zend_hash_exists(const HashTable *ht, zend_string *key)
{
Bucket *p;
@@ -1432,7 +1426,7 @@ ZEND_API int zend_hash_exists(const HashTable *ht, zend_string *key)
return p ? 1 : 0;
}
ZEND_API int zend_hash_str_exists(const HashTable *ht, const char *str, int len)
ZEND_API zend_bool zend_hash_str_exists(const HashTable *ht, const char *str, size_t len)
{
zend_ulong h;
Bucket *p;
@@ -1455,7 +1449,7 @@ ZEND_API zval *zend_hash_index_find(const HashTable *ht, zend_ulong h)
IS_CONSISTENT(ht);
if (ht->u.flags & HASH_FLAG_PACKED) {
if (h >= 0 && h < ht->nNumUsed) {
if (h < ht->nNumUsed) {
p = ht->arData + h;
if (Z_TYPE(p->val) != IS_UNDEF) {
return &p->val;
@@ -1469,14 +1463,14 @@ ZEND_API zval *zend_hash_index_find(const HashTable *ht, zend_ulong h)
}
ZEND_API int zend_hash_index_exists(const HashTable *ht, zend_ulong h)
ZEND_API zend_bool zend_hash_index_exists(const HashTable *ht, zend_ulong h)
{
Bucket *p;
IS_CONSISTENT(ht);
if (ht->u.flags & HASH_FLAG_PACKED) {
if (h >= 0 && h < ht->nNumUsed) {
if (h < ht->nNumUsed) {
if (Z_TYPE(ht->arData[h].val) != IS_UNDEF) {
return 1;
}
@@ -1489,61 +1483,9 @@ ZEND_API int zend_hash_index_exists(const HashTable *ht, zend_ulong h)
}
ZEND_API int zend_hash_get_pointer(const HashTable *ht, HashPointer *ptr)
{
ptr->pos = ht->nInternalPointer;
ptr->ht = (HashTable*)ht;
if (ht->nInternalPointer != INVALID_IDX) {
ptr->h = ht->arData[ht->nInternalPointer].h;
return 1;
} else {
ptr->h = 0;
return 0;
}
}
ZEND_API int zend_hash_set_pointer(HashTable *ht, const HashPointer *ptr)
{
uint idx;
if (ptr->pos == INVALID_IDX) {
ht->nInternalPointer = INVALID_IDX;
} else if (ptr->ht != ht) {
IS_CONSISTENT(ht);
for (idx = 0; idx < ht->nNumUsed; idx++) {
if (Z_TYPE(ht->arData[idx].val) != IS_UNDEF) {
ht->nInternalPointer = idx;
return 0;
}
}
idx = INVALID_IDX;
return 0;
} else if (ht->nInternalPointer != ptr->pos) {
IS_CONSISTENT(ht);
if (ht->u.flags & HASH_FLAG_PACKED) {
if (ptr->h < ht->nNumUsed &&
Z_TYPE(ht->arData[ptr->h].val) != IS_UNDEF) {
ht->nInternalPointer = ptr->h;
return 1;
}
} else {
idx = ht->arHash[ptr->h & ht->nTableMask];
while (idx != INVALID_IDX) {
if (ht->arData[idx].h == ptr->h && idx == ptr->pos) {
ht->nInternalPointer = idx;
return 1;
}
idx = Z_NEXT(ht->arData[idx].val);
}
}
return 0;
}
return 1;
}
ZEND_API void zend_hash_internal_pointer_reset_ex(HashTable *ht, HashPosition *pos)
{
uint idx;
uint32_t idx;
IS_CONSISTENT(ht);
for (idx = 0; idx < ht->nNumUsed; idx++) {
@@ -1561,7 +1503,7 @@ ZEND_API void zend_hash_internal_pointer_reset_ex(HashTable *ht, HashPosition *p
*/
ZEND_API void zend_hash_internal_pointer_end_ex(HashTable *ht, HashPosition *pos)
{
uint idx;
uint32_t idx;
IS_CONSISTENT(ht);
@@ -1579,7 +1521,7 @@ ZEND_API void zend_hash_internal_pointer_end_ex(HashTable *ht, HashPosition *pos
ZEND_API int zend_hash_move_forward_ex(HashTable *ht, HashPosition *pos)
{
uint idx = *pos;
uint32_t idx = *pos;
IS_CONSISTENT(ht);
@@ -1602,7 +1544,7 @@ ZEND_API int zend_hash_move_forward_ex(HashTable *ht, HashPosition *pos)
ZEND_API int zend_hash_move_backwards_ex(HashTable *ht, HashPosition *pos)
{
uint idx = *pos;
uint32_t idx = *pos;
IS_CONSISTENT(ht);
@@ -1625,7 +1567,7 @@ ZEND_API int zend_hash_move_backwards_ex(HashTable *ht, HashPosition *pos)
/* This function should be made binary safe */
ZEND_API int zend_hash_get_current_key_ex(const HashTable *ht, zend_string **str_index, zend_ulong *num_index, zend_bool duplicate, HashPosition *pos)
{
uint idx = *pos;
uint32_t idx = *pos;
Bucket *p;
IS_CONSISTENT(ht);
@@ -1648,7 +1590,7 @@ ZEND_API int zend_hash_get_current_key_ex(const HashTable *ht, zend_string **str
ZEND_API void zend_hash_get_current_key_zval_ex(const HashTable *ht, zval *key, HashPosition *pos)
{
uint idx = *pos;
uint32_t idx = *pos;
Bucket *p;
IS_CONSISTENT(ht);
@@ -1657,8 +1599,7 @@ ZEND_API void zend_hash_get_current_key_zval_ex(const HashTable *ht, zval *key,
} else {
p = ht->arData + idx;
if (p->key) {
ZVAL_STR(key, p->key);
zend_string_addref(p->key);
ZVAL_STR_COPY(key, p->key);
} else {
ZVAL_LONG(key, p->h);
}
@@ -1667,7 +1608,7 @@ ZEND_API void zend_hash_get_current_key_zval_ex(const HashTable *ht, zval *key,
ZEND_API int zend_hash_get_current_key_type_ex(HashTable *ht, HashPosition *pos)
{
uint idx = *pos;
uint32_t idx = *pos;
Bucket *p;
IS_CONSISTENT(ht);
@@ -1685,7 +1626,7 @@ ZEND_API int zend_hash_get_current_key_type_ex(HashTable *ht, HashPosition *pos)
ZEND_API zval *zend_hash_get_current_data_ex(HashTable *ht, HashPosition *pos)
{
uint idx = *pos;
uint32_t idx = *pos;
Bucket *p;
IS_CONSISTENT(ht);
@@ -1698,10 +1639,10 @@ ZEND_API zval *zend_hash_get_current_data_ex(HashTable *ht, HashPosition *pos)
}
ZEND_API int zend_hash_sort(HashTable *ht, sort_func_t sort_func,
compare_func_t compar, int renumber TSRMLS_DC)
compare_func_t compar, zend_bool renumber TSRMLS_DC)
{
Bucket *p;
int i, j;
uint32_t i, j;
IS_CONSISTENT(ht);
@@ -1763,7 +1704,7 @@ ZEND_API int zend_hash_sort(HashTable *ht, sort_func_t sort_func,
ZEND_API int zend_hash_compare(HashTable *ht1, HashTable *ht2, compare_func_t compar, zend_bool ordered TSRMLS_DC)
{
uint idx1, idx2;
uint32_t idx1, idx2;
Bucket *p1, *p2 = NULL;
int result;
zval *pData1, *pData2;
@@ -1867,9 +1808,9 @@ ZEND_API int zend_hash_compare(HashTable *ht1, HashTable *ht2, compare_func_t co
}
ZEND_API zval *zend_hash_minmax(const HashTable *ht, compare_func_t compar, int flag TSRMLS_DC)
ZEND_API zval *zend_hash_minmax(const HashTable *ht, compare_func_t compar, uint32_t flag TSRMLS_DC)
{
uint idx;
uint32_t idx;
Bucket *p, *res;
IS_CONSISTENT(ht);
@@ -1904,6 +1845,56 @@ ZEND_API zval *zend_hash_minmax(const HashTable *ht, compare_func_t compar, int
return &res->val;
}
ZEND_API int _zend_handle_numeric_str_ex(const char *key, size_t length, zend_ulong *idx)
{
register const char *tmp = key;
const char *end;
if (*tmp > '9') {
return 0;
} else if (*tmp < '0') {
if (*tmp != '-') {
return 0;
}
tmp++;
if (*tmp > '9' || *tmp < '0') {
return 0;
}
}
/* possibly a numeric index */
end = key + length;
if ((*end != '\0') /* not a null terminated string */
|| (*tmp == '0' && length > 1) /* numbers with leading zeros */
|| (end - tmp > MAX_LENGTH_OF_LONG - 1) /* number too long */
|| (SIZEOF_ZEND_LONG == 4 &&
end - tmp == MAX_LENGTH_OF_LONG - 1 &&
*tmp > '2')) { /* overflow */
return 0;
}
*idx = (*tmp - '0');
while (1) {
++tmp;
if (tmp == end) {
if (*key == '-') {
if (*idx-1 > ZEND_LONG_MAX) { /* overflow */
return 0;
}
*idx = 0 - *idx;
} else if (*idx > ZEND_LONG_MAX) { /* overflow */
return 0;
}
return 1;
}
if (*tmp <= '9' && *tmp >= '0') {
*idx = (*idx * 10) + (*tmp - '0');
} else {
return 0;
}
}
}
/*
* Local variables:
* tab-width: 4

View File

@@ -22,21 +22,18 @@
#ifndef ZEND_HASH_H
#define ZEND_HASH_H
#include <sys/types.h>
#include "zend.h"
#define HASH_KEY_IS_STRING 1
#define HASH_KEY_IS_LONG 2
#define HASH_KEY_NON_EXISTENT 3
#define HASH_KEY_NON_EXISTANT HASH_KEY_NON_EXISTENT /* Keeping old define (with typo) for backward compatibility */
#define HASH_UPDATE (1<<0)
#define HASH_ADD (1<<1)
#define HASH_NEXT_INSERT (1<<2)
#define HASH_UPDATE_INDIRECT (1<<3)
#define HASH_ADD_NEW (1<<4)
#define HASH_UPDATE_INDIRECT (1<<2)
#define HASH_ADD_NEW (1<<3)
#define INVALID_IDX ((uint)-1)
#define INVALID_IDX ((uint32_t) -1)
#define HASH_FLAG_PERSISTENT (1<<0)
#define HASH_FLAG_APPLY_PROTECTION (1<<1)
@@ -45,30 +42,30 @@
#define HASH_MASK_CONSISTENCY 0x60
typedef struct _zend_hash_key {
zend_ulong h;
zend_ulong h;
zend_string *key;
} zend_hash_key;
typedef zend_bool (*merge_checker_func_t)(HashTable *target_ht, zval *source_data, zend_hash_key *hash_key, void *pParam);
typedef uint HashPosition;
typedef uint32_t HashPosition;
BEGIN_EXTERN_C()
/* startup/shutdown */
ZEND_API void _zend_hash_init(HashTable *ht, uint nSize, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC);
ZEND_API void _zend_hash_init_ex(HashTable *ht, uint nSize, dtor_func_t pDestructor, zend_bool persistent, zend_bool bApplyProtection ZEND_FILE_LINE_DC);
ZEND_API void _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC);
ZEND_API void _zend_hash_init_ex(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent, zend_bool bApplyProtection ZEND_FILE_LINE_DC);
ZEND_API void zend_hash_destroy(HashTable *ht);
ZEND_API void zend_hash_clean(HashTable *ht);
#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent) _zend_hash_init((ht), (nSize), (pDestructor), (persistent) ZEND_FILE_LINE_CC)
#define zend_hash_init_ex(ht, nSize, pHashFunction, pDestructor, persistent, bApplyProtection) _zend_hash_init_ex((ht), (nSize), (pDestructor), (persistent), (bApplyProtection) ZEND_FILE_LINE_CC)
ZEND_API void zend_hash_real_init(HashTable *ht, int packed);
ZEND_API void zend_hash_real_init(HashTable *ht, zend_bool packed);
ZEND_API void zend_hash_packed_to_hash(HashTable *ht);
ZEND_API void zend_hash_to_packed(HashTable *ht);
/* additions/updates/changes */
ZEND_API zval *_zend_hash_add_or_update(HashTable *ht, zend_string *key, zval *pData, int flag ZEND_FILE_LINE_DC);
ZEND_API zval *_zend_hash_add_or_update(HashTable *ht, zend_string *key, zval *pData, uint32_t flag ZEND_FILE_LINE_DC);
ZEND_API zval *_zend_hash_update(HashTable *ht, zend_string *key,zval *pData ZEND_FILE_LINE_DC);
ZEND_API zval *_zend_hash_update_ind(HashTable *ht, zend_string *key,zval *pData ZEND_FILE_LINE_DC);
ZEND_API zval *_zend_hash_add(HashTable *ht, zend_string *key,zval *pData ZEND_FILE_LINE_DC);
@@ -83,11 +80,11 @@ ZEND_API zval *_zend_hash_add_new(HashTable *ht, zend_string *key,zval *pData ZE
#define zend_hash_add_new(ht, key, pData) \
_zend_hash_add_new(ht, key, pData ZEND_FILE_LINE_CC)
ZEND_API zval *_zend_hash_str_add_or_update(HashTable *ht, const char *key, int len, zval *pData, int flag ZEND_FILE_LINE_DC);
ZEND_API zval *_zend_hash_str_update(HashTable *ht, const char *key, int len, zval *pData ZEND_FILE_LINE_DC);
ZEND_API zval *_zend_hash_str_update_ind(HashTable *ht, const char *key, int len, zval *pData ZEND_FILE_LINE_DC);
ZEND_API zval *_zend_hash_str_add(HashTable *ht, const char *key, int len, zval *pData ZEND_FILE_LINE_DC);
ZEND_API zval *_zend_hash_str_add_new(HashTable *ht, const char *key, int len, zval *pData ZEND_FILE_LINE_DC);
ZEND_API zval *_zend_hash_str_add_or_update(HashTable *ht, const char *key, size_t len, zval *pData, uint32_t flag ZEND_FILE_LINE_DC);
ZEND_API zval *_zend_hash_str_update(HashTable *ht, const char *key, size_t len, zval *pData ZEND_FILE_LINE_DC);
ZEND_API zval *_zend_hash_str_update_ind(HashTable *ht, const char *key, size_t len, zval *pData ZEND_FILE_LINE_DC);
ZEND_API zval *_zend_hash_str_add(HashTable *ht, const char *key, size_t len, zval *pData ZEND_FILE_LINE_DC);
ZEND_API zval *_zend_hash_str_add_new(HashTable *ht, const char *key, size_t len, zval *pData ZEND_FILE_LINE_DC);
#define zend_hash_str_update(ht, key, len, pData) \
_zend_hash_str_update(ht, key, len, pData ZEND_FILE_LINE_CC)
@@ -98,7 +95,7 @@ ZEND_API zval *_zend_hash_str_add_new(HashTable *ht, const char *key, int len, z
#define zend_hash_str_add_new(ht, key, len, pData) \
_zend_hash_str_add_new(ht, key, len, pData ZEND_FILE_LINE_CC)
ZEND_API zval *_zend_hash_index_update_or_next_insert(HashTable *ht, zend_ulong h, zval *pData, int flag ZEND_FILE_LINE_DC);
ZEND_API zval *_zend_hash_index_add_or_update(HashTable *ht, zend_ulong h, zval *pData, uint32_t flag ZEND_FILE_LINE_DC);
ZEND_API zval *_zend_hash_index_add(HashTable *ht, zend_ulong h, zval *pData ZEND_FILE_LINE_DC);
ZEND_API zval *_zend_hash_index_add_new(HashTable *ht, zend_ulong h, zval *pData ZEND_FILE_LINE_DC);
ZEND_API zval *_zend_hash_index_update(HashTable *ht, zend_ulong h, zval *pData ZEND_FILE_LINE_DC);
@@ -118,7 +115,7 @@ ZEND_API zval *_zend_hash_next_index_insert_new(HashTable *ht, zval *pData ZEND_
ZEND_API zval *zend_hash_index_add_empty_element(HashTable *ht, zend_ulong h);
ZEND_API zval *zend_hash_add_empty_element(HashTable *ht, zend_string *key);
ZEND_API zval *zend_hash_str_add_empty_element(HashTable *ht, const char *key, int len);
ZEND_API zval *zend_hash_str_add_empty_element(HashTable *ht, const char *key, size_t len);
#define ZEND_HASH_APPLY_KEEP 0
#define ZEND_HASH_APPLY_REMOVE 1<<0
@@ -146,19 +143,19 @@ ZEND_API void zend_hash_reverse_apply(HashTable *ht, apply_func_t apply_func TSR
/* Deletes */
ZEND_API int zend_hash_del(HashTable *ht, zend_string *key);
ZEND_API int zend_hash_del_ind(HashTable *ht, zend_string *key);
ZEND_API int zend_hash_str_del(HashTable *ht, const char *key, int len);
ZEND_API int zend_hash_str_del_ind(HashTable *ht, const char *key, int len);
ZEND_API int zend_hash_str_del(HashTable *ht, const char *key, size_t len);
ZEND_API int zend_hash_str_del_ind(HashTable *ht, const char *key, size_t len);
ZEND_API int zend_hash_index_del(HashTable *ht, zend_ulong h);
/* Data retreival */
ZEND_API zval *zend_hash_find(const HashTable *ht, zend_string *key);
ZEND_API zval *zend_hash_str_find(const HashTable *ht, const char *key, int len);
ZEND_API zval *zend_hash_str_find(const HashTable *ht, const char *key, size_t len);
ZEND_API zval *zend_hash_index_find(const HashTable *ht, zend_ulong h);
/* Misc */
ZEND_API int zend_hash_exists(const HashTable *ht, zend_string *key);
ZEND_API int zend_hash_str_exists(const HashTable *ht, const char *str, int len);
ZEND_API int zend_hash_index_exists(const HashTable *ht, zend_ulong h);
ZEND_API zend_bool zend_hash_exists(const HashTable *ht, zend_string *key);
ZEND_API zend_bool zend_hash_str_exists(const HashTable *ht, const char *str, size_t len);
ZEND_API zend_bool zend_hash_index_exists(const HashTable *ht, zend_ulong h);
/* traversing */
#define zend_hash_has_more_elements_ex(ht, pos) \
@@ -178,9 +175,6 @@ typedef struct _HashPointer {
zend_ulong h;
} HashPointer;
ZEND_API int zend_hash_get_pointer(const HashTable *ht, HashPointer *ptr);
ZEND_API int zend_hash_set_pointer(HashTable *ht, const HashPointer *ptr);
#define zend_hash_has_more_elements(ht) \
zend_hash_has_more_elements_ex(ht, &(ht)->nInternalPointer)
#define zend_hash_move_forward(ht) \
@@ -202,11 +196,11 @@ ZEND_API int zend_hash_set_pointer(HashTable *ht, const HashPointer *ptr);
/* Copying, merging and sorting */
ZEND_API void zend_hash_copy(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor);
ZEND_API void _zend_hash_merge(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, int overwrite ZEND_FILE_LINE_DC);
ZEND_API void _zend_hash_merge(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, zend_bool overwrite ZEND_FILE_LINE_DC);
ZEND_API void zend_hash_merge_ex(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, merge_checker_func_t pMergeSource, void *pParam);
ZEND_API int zend_hash_sort(HashTable *ht, sort_func_t sort_func, compare_func_t compare_func, int renumber TSRMLS_DC);
ZEND_API int zend_hash_sort(HashTable *ht, sort_func_t sort_func, compare_func_t compare_func, zend_bool renumber TSRMLS_DC);
ZEND_API int zend_hash_compare(HashTable *ht1, HashTable *ht2, compare_func_t compar, zend_bool ordered TSRMLS_DC);
ZEND_API zval *zend_hash_minmax(const HashTable *ht, compare_func_t compar, int flag TSRMLS_DC);
ZEND_API zval *zend_hash_minmax(const HashTable *ht, compare_func_t compar, uint32_t flag TSRMLS_DC);
#define zend_hash_merge(target, source, pCopyConstructor, overwrite) \
_zend_hash_merge(target, source, pCopyConstructor, overwrite ZEND_FILE_LINE_CC)
@@ -235,10 +229,11 @@ END_EXTERN_C()
#define ZEND_INIT_SYMTABLE_EX(ht, n, persistent) \
zend_hash_init(ht, n, NULL, ZVAL_PTR_DTOR, persistent)
static inline int _zend_handle_numeric_str(const char *key, size_t length, zend_ulong *idx)
ZEND_API int _zend_handle_numeric_str_ex(const char *key, size_t length, zend_ulong *idx);
static zend_always_inline int _zend_handle_numeric_str(const char *key, size_t length, zend_ulong *idx)
{
register const char *tmp = key;
const char *end;
if (*tmp > '9') {
return 0;
@@ -251,48 +246,17 @@ static inline int _zend_handle_numeric_str(const char *key, size_t length, zend_
return 0;
}
}
/* possibly a numeric index */
end = key + length;
if ((*end != '\0') /* not a null terminated string */
|| (*tmp == '0' && length > 1) /* numbers with leading zeros */
|| (end - tmp > MAX_LENGTH_OF_LONG - 1) /* number too long */
|| (SIZEOF_ZEND_LONG == 4 &&
end - tmp == MAX_LENGTH_OF_LONG - 1 &&
*tmp > '2')) { /* overflow */
return 0;
}
*idx = (*tmp - '0');
while (1) {
++tmp;
if (tmp == end) {
if (*key == '-') {
if (*idx-1 > ZEND_LONG_MAX) { /* overflow */
return 0;
}
*idx = 0 - *idx;
} else if (*idx > ZEND_LONG_MAX) { /* overflow */
return 0;
}
return 1;
}
if (*tmp <= '9' && *tmp >= '0') {
*idx = (*idx * 10) + (*tmp - '0');
} else {
return 0;
}
}
return _zend_handle_numeric_str_ex(key, length, idx);
}
#define ZEND_HANDLE_NUMERIC_STR(key, length, idx) \
_zend_handle_numeric_str(key, length, &idx)
#define ZEND_HANDLE_NUMERIC(key, idx) \
_zend_handle_numeric_str((key)->val, (key)->len, &idx)
ZEND_HANDLE_NUMERIC_STR((key)->val, (key)->len, idx)
static inline zval *zend_hash_find_ind(const HashTable *ht, zend_string *key)
static zend_always_inline zval *zend_hash_find_ind(const HashTable *ht, zend_string *key)
{
zval *zv;
@@ -301,7 +265,7 @@ static inline zval *zend_hash_find_ind(const HashTable *ht, zend_string *key)
}
static inline int zend_hash_exists_ind(const HashTable *ht, zend_string *key)
static zend_always_inline int zend_hash_exists_ind(const HashTable *ht, zend_string *key)
{
zval *zv;
@@ -311,7 +275,7 @@ static inline int zend_hash_exists_ind(const HashTable *ht, zend_string *key)
}
static inline zval *zend_hash_str_find_ind(const HashTable *ht, const char *str, int len)
static zend_always_inline zval *zend_hash_str_find_ind(const HashTable *ht, const char *str, int len)
{
zval *zv;
@@ -320,7 +284,7 @@ static inline zval *zend_hash_str_find_ind(const HashTable *ht, const char *str,
}
static inline zval *zend_symtable_update(HashTable *ht, zend_string *key, zval *pData)
static zend_always_inline zval *zend_symtable_update(HashTable *ht, zend_string *key, zval *pData)
{
zend_ulong idx;
@@ -332,7 +296,7 @@ static inline zval *zend_symtable_update(HashTable *ht, zend_string *key, zval *
}
static inline zval *zend_symtable_update_ind(HashTable *ht, zend_string *key, zval *pData)
static zend_always_inline zval *zend_symtable_update_ind(HashTable *ht, zend_string *key, zval *pData)
{
zend_ulong idx;
@@ -344,7 +308,7 @@ static inline zval *zend_symtable_update_ind(HashTable *ht, zend_string *key, zv
}
static inline int zend_symtable_del(HashTable *ht, zend_string *key)
static zend_always_inline int zend_symtable_del(HashTable *ht, zend_string *key)
{
zend_ulong idx;
@@ -356,7 +320,7 @@ static inline int zend_symtable_del(HashTable *ht, zend_string *key)
}
static inline int zend_symtable_del_ind(HashTable *ht, zend_string *key)
static zend_always_inline int zend_symtable_del_ind(HashTable *ht, zend_string *key)
{
zend_ulong idx;
@@ -368,7 +332,7 @@ static inline int zend_symtable_del_ind(HashTable *ht, zend_string *key)
}
static inline zval *zend_symtable_find(const HashTable *ht, zend_string *key)
static zend_always_inline zval *zend_symtable_find(const HashTable *ht, zend_string *key)
{
zend_ulong idx;
@@ -380,7 +344,7 @@ static inline zval *zend_symtable_find(const HashTable *ht, zend_string *key)
}
static inline zval *zend_symtable_find_ind(const HashTable *ht, zend_string *key)
static zend_always_inline zval *zend_symtable_find_ind(const HashTable *ht, zend_string *key)
{
zend_ulong idx;
@@ -392,7 +356,7 @@ static inline zval *zend_symtable_find_ind(const HashTable *ht, zend_string *key
}
static inline int zend_symtable_exists(HashTable *ht, zend_string *key)
static zend_always_inline int zend_symtable_exists(HashTable *ht, zend_string *key)
{
zend_ulong idx;
@@ -404,7 +368,7 @@ static inline int zend_symtable_exists(HashTable *ht, zend_string *key)
}
static inline zval *zend_symtable_str_update(HashTable *ht, const char *str, int len, zval *pData)
static zend_always_inline zval *zend_symtable_str_update(HashTable *ht, const char *str, int len, zval *pData)
{
zend_ulong idx;
@@ -416,7 +380,7 @@ static inline zval *zend_symtable_str_update(HashTable *ht, const char *str, int
}
static inline zval *zend_symtable_str_update_ind(HashTable *ht, const char *str, int len, zval *pData)
static zend_always_inline zval *zend_symtable_str_update_ind(HashTable *ht, const char *str, int len, zval *pData)
{
zend_ulong idx;
@@ -428,7 +392,7 @@ static inline zval *zend_symtable_str_update_ind(HashTable *ht, const char *str,
}
static inline int zend_symtable_str_del(HashTable *ht, const char *str, int len)
static zend_always_inline int zend_symtable_str_del(HashTable *ht, const char *str, int len)
{
zend_ulong idx;
@@ -440,7 +404,7 @@ static inline int zend_symtable_str_del(HashTable *ht, const char *str, int len)
}
static inline int zend_symtable_str_del_ind(HashTable *ht, const char *str, int len)
static zend_always_inline int zend_symtable_str_del_ind(HashTable *ht, const char *str, int len)
{
zend_ulong idx;
@@ -452,7 +416,7 @@ static inline int zend_symtable_str_del_ind(HashTable *ht, const char *str, int
}
static inline zval *zend_symtable_str_find(HashTable *ht, const char *str, int len)
static zend_always_inline zval *zend_symtable_str_find(HashTable *ht, const char *str, int len)
{
zend_ulong idx;
@@ -464,7 +428,7 @@ static inline zval *zend_symtable_str_find(HashTable *ht, const char *str, int l
}
static inline int zend_symtable_str_exists(HashTable *ht, const char *str, int len)
static zend_always_inline int zend_symtable_str_exists(HashTable *ht, const char *str, int len)
{
zend_ulong idx;
@@ -475,7 +439,7 @@ static inline int zend_symtable_str_exists(HashTable *ht, const char *str, int l
}
}
static inline void *zend_hash_add_ptr(HashTable *ht, zend_string *key, void *pData)
static zend_always_inline void *zend_hash_add_ptr(HashTable *ht, zend_string *key, void *pData)
{
zval tmp, *zv;
@@ -484,7 +448,7 @@ static inline void *zend_hash_add_ptr(HashTable *ht, zend_string *key, void *pDa
return zv ? Z_PTR_P(zv) : NULL;
}
static inline void *zend_hash_add_new_ptr(HashTable *ht, zend_string *key, void *pData)
static zend_always_inline void *zend_hash_add_new_ptr(HashTable *ht, zend_string *key, void *pData)
{
zval tmp, *zv;
@@ -493,7 +457,7 @@ static inline void *zend_hash_add_new_ptr(HashTable *ht, zend_string *key, void
return zv ? Z_PTR_P(zv) : NULL;
}
static inline void *zend_hash_str_add_ptr(HashTable *ht, const char *str, int len, void *pData)
static zend_always_inline void *zend_hash_str_add_ptr(HashTable *ht, const char *str, int len, void *pData)
{
zval tmp, *zv;
@@ -502,7 +466,7 @@ static inline void *zend_hash_str_add_ptr(HashTable *ht, const char *str, int le
return zv ? Z_PTR_P(zv) : NULL;
}
static inline void *zend_hash_update_ptr(HashTable *ht, zend_string *key, void *pData)
static zend_always_inline void *zend_hash_update_ptr(HashTable *ht, zend_string *key, void *pData)
{
zval tmp, *zv;
@@ -511,7 +475,7 @@ static inline void *zend_hash_update_ptr(HashTable *ht, zend_string *key, void *
return zv ? Z_PTR_P(zv) : NULL;
}
static inline void *zend_hash_str_update_ptr(HashTable *ht, const char *str, int len, void *pData)
static zend_always_inline void *zend_hash_str_update_ptr(HashTable *ht, const char *str, int len, void *pData)
{
zval tmp, *zv;
@@ -520,7 +484,7 @@ static inline void *zend_hash_str_update_ptr(HashTable *ht, const char *str, int
return zv ? Z_PTR_P(zv) : NULL;
}
static inline void *zend_hash_add_mem(HashTable *ht, zend_string *key, void *pData, size_t size)
static zend_always_inline void *zend_hash_add_mem(HashTable *ht, zend_string *key, void *pData, size_t size)
{
zval tmp, *zv;
@@ -533,7 +497,7 @@ static inline void *zend_hash_add_mem(HashTable *ht, zend_string *key, void *pDa
return NULL;
}
static inline void *zend_hash_str_add_mem(HashTable *ht, const char *str, int len, void *pData, size_t size)
static zend_always_inline void *zend_hash_str_add_mem(HashTable *ht, const char *str, int len, void *pData, size_t size)
{
zval tmp, *zv;
@@ -546,7 +510,7 @@ static inline void *zend_hash_str_add_mem(HashTable *ht, const char *str, int le
return NULL;
}
static inline void *zend_hash_update_mem(HashTable *ht, zend_string *key, void *pData, size_t size)
static zend_always_inline void *zend_hash_update_mem(HashTable *ht, zend_string *key, void *pData, size_t size)
{
void *p;
@@ -555,7 +519,7 @@ static inline void *zend_hash_update_mem(HashTable *ht, zend_string *key, void *
return zend_hash_update_ptr(ht, key, p);
}
static inline void *zend_hash_str_update_mem(HashTable *ht, const char *str, int len, void *pData, size_t size)
static zend_always_inline void *zend_hash_str_update_mem(HashTable *ht, const char *str, int len, void *pData, size_t size)
{
void *p;
@@ -564,7 +528,7 @@ static inline void *zend_hash_str_update_mem(HashTable *ht, const char *str, int
return zend_hash_str_update_ptr(ht, str, len, p);
}
static inline void *zend_hash_index_update_ptr(HashTable *ht, zend_ulong h, void *pData)
static zend_always_inline void *zend_hash_index_update_ptr(HashTable *ht, zend_ulong h, void *pData)
{
zval tmp, *zv;
@@ -573,7 +537,7 @@ static inline void *zend_hash_index_update_ptr(HashTable *ht, zend_ulong h, void
return zv ? Z_PTR_P(zv) : NULL;
}
static inline void *zend_hash_next_index_insert_ptr(HashTable *ht, void *pData)
static zend_always_inline void *zend_hash_next_index_insert_ptr(HashTable *ht, void *pData)
{
zval tmp, *zv;
@@ -582,7 +546,7 @@ static inline void *zend_hash_next_index_insert_ptr(HashTable *ht, void *pData)
return zv ? Z_PTR_P(zv) : NULL;
}
static inline void *zend_hash_index_update_mem(HashTable *ht, zend_ulong h, void *pData, size_t size)
static zend_always_inline void *zend_hash_index_update_mem(HashTable *ht, zend_ulong h, void *pData, size_t size)
{
void *p;
@@ -591,7 +555,7 @@ static inline void *zend_hash_index_update_mem(HashTable *ht, zend_ulong h, void
return zend_hash_index_update_ptr(ht, h, p);
}
static inline void *zend_hash_next_index_insert_mem(HashTable *ht, void *pData, size_t size)
static zend_always_inline void *zend_hash_next_index_insert_mem(HashTable *ht, void *pData, size_t size)
{
zval tmp, *zv;
@@ -604,7 +568,7 @@ static inline void *zend_hash_next_index_insert_mem(HashTable *ht, void *pData,
return NULL;
}
static inline void *zend_hash_find_ptr(const HashTable *ht, zend_string *key)
static zend_always_inline void *zend_hash_find_ptr(const HashTable *ht, zend_string *key)
{
zval *zv;
@@ -612,7 +576,7 @@ static inline void *zend_hash_find_ptr(const HashTable *ht, zend_string *key)
return zv ? Z_PTR_P(zv) : NULL;
}
static inline void *zend_hash_str_find_ptr(const HashTable *ht, const char *str, int len)
static zend_always_inline void *zend_hash_str_find_ptr(const HashTable *ht, const char *str, int len)
{
zval *zv;
@@ -620,7 +584,7 @@ static inline void *zend_hash_str_find_ptr(const HashTable *ht, const char *str,
return zv ? Z_PTR_P(zv) : NULL;
}
static inline void *zend_hash_index_find_ptr(const HashTable *ht, zend_ulong h)
static zend_always_inline void *zend_hash_index_find_ptr(const HashTable *ht, zend_ulong h)
{
zval *zv;
@@ -628,7 +592,7 @@ static inline void *zend_hash_index_find_ptr(const HashTable *ht, zend_ulong h)
return zv ? Z_PTR_P(zv) : NULL;
}
static inline void *zend_symtable_str_find_ptr(HashTable *ht, const char *str, int len)
static zend_always_inline void *zend_symtable_str_find_ptr(HashTable *ht, const char *str, int len)
{
zend_ulong idx;
@@ -639,7 +603,7 @@ static inline void *zend_symtable_str_find_ptr(HashTable *ht, const char *str, i
}
}
static inline void *zend_hash_get_current_data_ptr_ex(HashTable *ht, HashPosition *pos)
static zend_always_inline void *zend_hash_get_current_data_ptr_ex(HashTable *ht, HashPosition *pos)
{
zval *zv;

1581
Zend/zend_inheritance.c Normal file

File diff suppressed because it is too large Load Diff

46
Zend/zend_inheritance.h Normal file
View File

@@ -0,0 +1,46 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 2.00 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.zend.com/license/2_00.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#ifndef ZEND_INHERITANCE_H
#define ZEND_INHERITANCE_H
#include "zend.h"
BEGIN_EXTERN_C()
ZEND_API void zend_do_inherit_interfaces(zend_class_entry *ce, const zend_class_entry *iface TSRMLS_DC);
ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry *iface TSRMLS_DC);
ZEND_API void zend_do_implement_trait(zend_class_entry *ce, zend_class_entry *trait TSRMLS_DC);
ZEND_API void zend_do_bind_traits(zend_class_entry *ce TSRMLS_DC);
ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent_ce TSRMLS_DC);
void zend_do_early_binding(TSRMLS_D);
END_EXTERN_C()
#endif
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* indent-tabs-mode: t
* End:
*/

View File

@@ -56,7 +56,7 @@ static int zend_restore_ini_entry_cb(zend_ini_entry *ini_entry, int stage TSRMLS
/* even if on_modify bails out, we have to continue on with restoring,
since there can be allocated variables that would be freed on MM shutdown
and would lead to memory corruption later ini entry is modified again */
result = ini_entry->on_modify(ini_entry, ini_entry->orig_value, ini_entry->orig_value_length, ini_entry->mh_arg1, ini_entry->mh_arg2, ini_entry->mh_arg3, stage TSRMLS_CC);
result = ini_entry->on_modify(ini_entry, ini_entry->orig_value, ini_entry->mh_arg1, ini_entry->mh_arg2, ini_entry->mh_arg3, stage TSRMLS_CC);
} zend_end_try();
}
if (stage == ZEND_INI_STAGE_RUNTIME && result == FAILURE) {
@@ -64,14 +64,12 @@ static int zend_restore_ini_entry_cb(zend_ini_entry *ini_entry, int stage TSRMLS
return 1;
}
if (ini_entry->value != ini_entry->orig_value) {
efree(ini_entry->value);
zend_string_release(ini_entry->value);
}
ini_entry->value = ini_entry->orig_value;
ini_entry->value_length = ini_entry->orig_value_length;
ini_entry->modifiable = ini_entry->orig_modifiable;
ini_entry->modified = 0;
ini_entry->orig_value = NULL;
ini_entry->orig_value_length = 0;
ini_entry->orig_modifiable = 0;
}
return 0;
@@ -86,9 +84,18 @@ static int zend_restore_ini_entry_wrapper(zval *el TSRMLS_DC) /* {{{ */
}
/* }}} */
static void _free_ptr(zval *zv) /* {{{ */
static void free_ini_entry(zval *zv) /* {{{ */
{
free(Z_PTR_P(zv));
zend_ini_entry *entry = (zend_ini_entry*)Z_PTR_P(zv);
zend_string_release(entry->name);
if (entry->value) {
zend_string_release(entry->value);
}
if (entry->orig_value) {
zend_string_release(entry->orig_value);
}
free(entry);
}
/* }}} */
@@ -102,7 +109,7 @@ ZEND_API int zend_ini_startup(TSRMLS_D) /* {{{ */
EG(ini_directives) = registered_zend_ini_directives;
EG(modified_ini_directives) = NULL;
EG(error_reporting_ini_entry) = NULL;
zend_hash_init_ex(registered_zend_ini_directives, 128, NULL, _free_ptr, 1, 0);
zend_hash_init_ex(registered_zend_ini_directives, 128, NULL, free_ini_entry, 1, 0);
return SUCCESS;
}
/* }}} */
@@ -136,13 +143,32 @@ ZEND_API int zend_ini_deactivate(TSRMLS_D) /* {{{ */
/* }}} */
#ifdef ZTS
static void copy_ini_entry(zval *zv) /* {{{ */
{
zend_ini_entry *old_entry = (zend_ini_entry*)Z_PTR_P(zv);
zend_ini_entry *new_entry = pemalloc(sizeof(zend_ini_entry), 1);
Z_PTR_P(zv) = new_entry;
memcpy(new_entry, old_entry, sizeof(zend_ini_entry));
if (old_entry->name) {
new_entry->name = zend_string_init(old_entry->name->val, old_entry->name->len, 1);
}
if (old_entry->value) {
new_entry->value = zend_string_init(old_entry->value->val, old_entry->value->len, 1);
}
if (old_entry->orig_value) {
new_entry->orig_value = zend_string_init(old_entry->orig_value->val, old_entry->orig_value->len, 1);
}
}
/* }}} */
ZEND_API int zend_copy_ini_directives(TSRMLS_D) /* {{{ */
{
EG(modified_ini_directives) = NULL;
EG(error_reporting_ini_entry) = NULL;
EG(ini_directives) = (HashTable *) malloc(sizeof(HashTable));
zend_hash_init_ex(EG(ini_directives), registered_zend_ini_directives->nNumOfElements, NULL, NULL, 1, 0);
zend_hash_copy(EG(ini_directives), registered_zend_ini_directives, NULL);
zend_hash_init_ex(EG(ini_directives), registered_zend_ini_directives->nNumOfElements, NULL, free_ini_entry, 1, 0);
zend_hash_copy(EG(ini_directives), registered_zend_ini_directives, copy_ini_entry);
return SUCCESS;
}
/* }}} */
@@ -177,13 +203,11 @@ ZEND_API void zend_ini_sort_entries(TSRMLS_D) /* {{{ */
/*
* Registration / unregistration
*/
ZEND_API int zend_register_ini_entries(const zend_ini_entry *ini_entry, int module_number TSRMLS_DC) /* {{{ */
ZEND_API int zend_register_ini_entries(const zend_ini_entry_def *ini_entry, int module_number TSRMLS_DC) /* {{{ */
{
const zend_ini_entry *p = ini_entry;
zend_ini_entry *hashed_ini_entry;
zval default_value;
zend_ini_entry *p;
zval *default_value;
HashTable *directives = registered_zend_ini_directives;
zend_bool config_directive_success = 0;
#ifdef ZTS
/* if we are called during the request, eg: from dl(),
@@ -199,26 +223,42 @@ ZEND_API int zend_register_ini_entries(const zend_ini_entry *ini_entry, int modu
}
#endif
while (p->name) {
config_directive_success = 0;
if ((hashed_ini_entry = zend_hash_str_add_mem(directives, p->name, p->name_length, (void*)p, sizeof(zend_ini_entry))) == NULL) {
while (ini_entry->name) {
p = pemalloc(sizeof(zend_ini_entry), 1);
p->name = zend_string_init(ini_entry->name, ini_entry->name_length, 1);
p->on_modify = ini_entry->on_modify;
p->mh_arg1 = ini_entry->mh_arg1;
p->mh_arg2 = ini_entry->mh_arg2;
p->mh_arg3 = ini_entry->mh_arg3;
p->value = NULL;
p->orig_value = NULL;
p->displayer = ini_entry->displayer;
p->modifiable = ini_entry->modifiable;
p->orig_modifiable = 0;
p->modified = 0;
p->module_number = module_number;
if (zend_hash_add_ptr(directives, p->name, (void*)p) == NULL) {
if (p->name) {
zend_string_release(p->name);
}
zend_unregister_ini_entries(module_number TSRMLS_CC);
return FAILURE;
}
hashed_ini_entry->module_number = module_number;
if ((zend_get_configuration_directive(p->name, p->name_length, &default_value)) == SUCCESS) {
if (!hashed_ini_entry->on_modify
|| hashed_ini_entry->on_modify(hashed_ini_entry, Z_STRVAL(default_value), Z_STRLEN(default_value), hashed_ini_entry->mh_arg1, hashed_ini_entry->mh_arg2, hashed_ini_entry->mh_arg3, ZEND_INI_STAGE_STARTUP TSRMLS_CC) == SUCCESS) {
hashed_ini_entry->value = Z_STRVAL(default_value);
hashed_ini_entry->value_length = Z_STRLEN(default_value);
config_directive_success = 1;
if (((default_value = zend_get_configuration_directive(p->name)) != NULL) &&
(!p->on_modify || p->on_modify(p, Z_STR_P(default_value), p->mh_arg1, p->mh_arg2, p->mh_arg3, ZEND_INI_STAGE_STARTUP TSRMLS_CC) == SUCCESS)) {
p->value = zend_string_copy(Z_STR_P(default_value));
} else {
p->value = ini_entry->value ?
zend_string_init(ini_entry->value, ini_entry->value_length, 1) : NULL;
if (p->on_modify) {
p->on_modify(p, p->value, p->mh_arg1, p->mh_arg2, p->mh_arg3, ZEND_INI_STAGE_STARTUP TSRMLS_CC);
}
}
if (!config_directive_success && hashed_ini_entry->on_modify) {
hashed_ini_entry->on_modify(hashed_ini_entry, hashed_ini_entry->value, hashed_ini_entry->value_length, hashed_ini_entry->mh_arg1, hashed_ini_entry->mh_arg2, hashed_ini_entry->mh_arg3, ZEND_INI_STAGE_STARTUP TSRMLS_CC);
}
p++;
ini_entry++;
}
return SUCCESS;
}
@@ -237,7 +277,7 @@ static int zend_ini_refresh_cache(zval *el, void *arg TSRMLS_DC) /* {{{ */
int stage = (int)(zend_intptr_t)arg;
if (p->on_modify) {
p->on_modify(p, p->value, p->value_length, p->mh_arg1, p->mh_arg2, p->mh_arg3, stage TSRMLS_CC);
p->on_modify(p, p->value, p->mh_arg1, p->mh_arg2, p->mh_arg3, stage TSRMLS_CC);
}
return 0;
}
@@ -250,18 +290,43 @@ ZEND_API void zend_ini_refresh_caches(int stage TSRMLS_DC) /* {{{ */
/* }}} */
#endif
ZEND_API int zend_alter_ini_entry(zend_string *name, char *new_value, uint new_value_length, int modify_type, int stage) /* {{{ */
ZEND_API int zend_alter_ini_entry(zend_string *name, zend_string *new_value, int modify_type, int stage) /* {{{ */
{
TSRMLS_FETCH();
return zend_alter_ini_entry_ex(name, new_value, new_value_length, modify_type, stage, 0 TSRMLS_CC);
return zend_alter_ini_entry_ex(name, new_value, modify_type, stage, 0 TSRMLS_CC);
}
/* }}} */
ZEND_API int zend_alter_ini_entry_ex(zend_string *name, char *new_value, uint new_value_length, int modify_type, int stage, int force_change TSRMLS_DC) /* {{{ */
ZEND_API int zend_alter_ini_entry_chars(zend_string *name, const char *value, size_t value_length, int modify_type, int stage) /* {{{ */
{
int ret;
zend_string *new_value;
TSRMLS_FETCH();
new_value = zend_string_init(value, value_length, stage != ZEND_INI_STAGE_RUNTIME);
ret = zend_alter_ini_entry_ex(name, new_value, modify_type, stage, 0 TSRMLS_CC);
zend_string_release(new_value);
return ret;
}
/* }}} */
ZEND_API int zend_alter_ini_entry_chars_ex(zend_string *name, const char *value, size_t value_length, int modify_type, int stage, int force_change TSRMLS_DC) /* {{{ */
{
int ret;
zend_string *new_value;
new_value = zend_string_init(value, value_length, stage != ZEND_INI_STAGE_RUNTIME);
ret = zend_alter_ini_entry_ex(name, new_value, modify_type, stage, force_change TSRMLS_CC);
zend_string_release(new_value);
return ret;
}
/* }}} */
ZEND_API int zend_alter_ini_entry_ex(zend_string *name, zend_string *new_value, int modify_type, int stage, int force_change TSRMLS_DC) /* {{{ */
{
zend_ini_entry *ini_entry;
char *duplicate;
zend_string *duplicate;
zend_bool modifiable;
zend_bool modified;
@@ -288,23 +353,21 @@ ZEND_API int zend_alter_ini_entry_ex(zend_string *name, char *new_value, uint ne
}
if (!modified) {
ini_entry->orig_value = ini_entry->value;
ini_entry->orig_value_length = ini_entry->value_length;
ini_entry->orig_modifiable = modifiable;
ini_entry->modified = 1;
zend_hash_add_ptr(EG(modified_ini_directives), name, ini_entry);
}
duplicate = estrndup(new_value, new_value_length);
duplicate = zend_string_copy(new_value);
if (!ini_entry->on_modify
|| ini_entry->on_modify(ini_entry, duplicate, new_value_length, ini_entry->mh_arg1, ini_entry->mh_arg2, ini_entry->mh_arg3, stage TSRMLS_CC) == SUCCESS) {
|| ini_entry->on_modify(ini_entry, duplicate, ini_entry->mh_arg1, ini_entry->mh_arg2, ini_entry->mh_arg3, stage TSRMLS_CC) == SUCCESS) {
if (modified && ini_entry->orig_value != ini_entry->value) { /* we already changed the value, free the changed value */
efree(ini_entry->value);
zend_string_release(ini_entry->value);
}
ini_entry->value = duplicate;
ini_entry->value_length = new_value_length;
} else {
efree(duplicate);
zend_string_release(duplicate);
return FAILURE;
}
@@ -360,9 +423,9 @@ ZEND_API zend_long zend_ini_long(char *name, uint name_length, int orig) /* {{{
ini_entry = zend_hash_str_find_ptr(EG(ini_directives), name, name_length);
if (ini_entry) {
if (orig && ini_entry->modified) {
return (ini_entry->orig_value ? ZEND_STRTOL(ini_entry->orig_value, NULL, 0) : 0);
return (ini_entry->orig_value ? ZEND_STRTOL(ini_entry->orig_value->val, NULL, 0) : 0);
} else {
return (ini_entry->value ? ZEND_STRTOL(ini_entry->value, NULL, 0) : 0);
return (ini_entry->value ? ZEND_STRTOL(ini_entry->value->val, NULL, 0) : 0);
}
}
@@ -378,9 +441,9 @@ ZEND_API double zend_ini_double(char *name, uint name_length, int orig) /* {{{ *
ini_entry = zend_hash_str_find_ptr(EG(ini_directives), name, name_length);
if (ini_entry) {
if (orig && ini_entry->modified) {
return (double) (ini_entry->orig_value ? zend_strtod(ini_entry->orig_value, NULL) : 0.0);
return (double) (ini_entry->orig_value ? zend_strtod(ini_entry->orig_value->val, NULL) : 0.0);
} else {
return (double) (ini_entry->value ? zend_strtod(ini_entry->value, NULL) : 0.0);
return (double) (ini_entry->value ? zend_strtod(ini_entry->value->val, NULL) : 0.0);
}
}
@@ -400,9 +463,9 @@ ZEND_API char *zend_ini_string_ex(char *name, uint name_length, int orig, zend_b
}
if (orig && ini_entry->modified) {
return ini_entry->orig_value;
return ini_entry->orig_value ? ini_entry->orig_value->val : NULL;
} else {
return ini_entry->value;
return ini_entry->value ? ini_entry->value->val : NULL;
}
} else {
if (exists) {
@@ -470,29 +533,26 @@ static void zend_ini_displayer_cb(zend_ini_entry *ini_entry, int type) /* {{{ */
ZEND_INI_DISP(zend_ini_boolean_displayer_cb) /* {{{ */
{
int value, tmp_value_len;
char *tmp_value;
int value;
zend_string *tmp_value;
if (type == ZEND_INI_DISPLAY_ORIG && ini_entry->modified) {
tmp_value = (ini_entry->orig_value ? ini_entry->orig_value : NULL );
tmp_value_len = ini_entry->orig_value_length;
} else if (ini_entry->value) {
tmp_value = ini_entry->value;
tmp_value_len = ini_entry->value_length;
} else {
tmp_value = NULL;
tmp_value_len = 0;
}
if (tmp_value) {
if (tmp_value_len == 4 && strcasecmp(tmp_value, "true") == 0) {
if (tmp_value->len == 4 && strcasecmp(tmp_value->val, "true") == 0) {
value = 1;
} else if (tmp_value_len == 3 && strcasecmp(tmp_value, "yes") == 0) {
} else if (tmp_value->len == 3 && strcasecmp(tmp_value->val, "yes") == 0) {
value = 1;
} else if (tmp_value_len == 2 && strcasecmp(tmp_value, "on") == 0) {
} else if (tmp_value->len == 2 && strcasecmp(tmp_value->val, "on") == 0) {
value = 1;
} else {
value = atoi(tmp_value);
value = atoi(tmp_value->val);
}
} else {
value = 0;
@@ -511,9 +571,9 @@ ZEND_INI_DISP(zend_ini_color_displayer_cb) /* {{{ */
char *value;
if (type == ZEND_INI_DISPLAY_ORIG && ini_entry->modified) {
value = ini_entry->orig_value;
value = ini_entry->orig_value->val;
} else if (ini_entry->value) {
value = ini_entry->value;
value = ini_entry->value->val;
} else {
value = NULL;
}
@@ -538,9 +598,9 @@ ZEND_INI_DISP(display_link_numbers) /* {{{ */
char *value;
if (type == ZEND_INI_DISPLAY_ORIG && ini_entry->modified) {
value = ini_entry->orig_value;
value = ini_entry->orig_value->val;
} else if (ini_entry->value) {
value = ini_entry->value;
value = ini_entry->value->val;
} else {
value = NULL;
}
@@ -569,17 +629,17 @@ ZEND_API ZEND_INI_MH(OnUpdateBool) /* {{{ */
p = (zend_bool *) (base+(size_t) mh_arg1);
if (new_value_length == 2 && strcasecmp("on", new_value) == 0) {
if (new_value->len == 2 && strcasecmp("on", new_value->val) == 0) {
*p = (zend_bool) 1;
}
else if (new_value_length == 3 && strcasecmp("yes", new_value) == 0) {
else if (new_value->len == 3 && strcasecmp("yes", new_value->val) == 0) {
*p = (zend_bool) 1;
}
else if (new_value_length == 4 && strcasecmp("true", new_value) == 0) {
else if (new_value->len == 4 && strcasecmp("true", new_value->val) == 0) {
*p = (zend_bool) 1;
}
else {
*p = (zend_bool) atoi(new_value);
*p = (zend_bool) atoi(new_value->val);
}
return SUCCESS;
}
@@ -598,7 +658,7 @@ ZEND_API ZEND_INI_MH(OnUpdateLong) /* {{{ */
p = (zend_long *) (base+(size_t) mh_arg1);
*p = zend_atol(new_value, new_value_length);
*p = zend_atol(new_value->val, new_value->len);
return SUCCESS;
}
/* }}} */
@@ -614,7 +674,7 @@ ZEND_API ZEND_INI_MH(OnUpdateLongGEZero) /* {{{ */
base = (char *) ts_resource(*((int *) mh_arg2));
#endif
tmp = zend_atol(new_value, new_value_length);
tmp = zend_atol(new_value->val, new_value->len);
if (tmp < 0) {
return FAILURE;
}
@@ -639,7 +699,7 @@ ZEND_API ZEND_INI_MH(OnUpdateReal) /* {{{ */
p = (double *) (base+(size_t) mh_arg1);
*p = zend_strtod(new_value, NULL);
*p = zend_strtod(new_value->val, NULL);
return SUCCESS;
}
/* }}} */
@@ -657,7 +717,7 @@ ZEND_API ZEND_INI_MH(OnUpdateString) /* {{{ */
p = (char **) (base+(size_t) mh_arg1);
*p = new_value;
*p = new_value ? new_value->val : NULL;
return SUCCESS;
}
/* }}} */
@@ -673,13 +733,13 @@ ZEND_API ZEND_INI_MH(OnUpdateStringUnempty) /* {{{ */
base = (char *) ts_resource(*((int *) mh_arg2));
#endif
if (new_value && !new_value[0]) {
if (new_value && !new_value->val[0]) {
return FAILURE;
}
p = (char **) (base+(size_t) mh_arg1);
*p = new_value;
*p = new_value ? new_value->val : NULL;
return SUCCESS;
}
/* }}} */

View File

@@ -27,28 +27,37 @@
#define ZEND_INI_ALL (ZEND_INI_USER|ZEND_INI_PERDIR|ZEND_INI_SYSTEM)
#define ZEND_INI_MH(name) int name(zend_ini_entry *entry, char *new_value, uint new_value_length, void *mh_arg1, void *mh_arg2, void *mh_arg3, int stage TSRMLS_DC)
#define ZEND_INI_MH(name) int name(zend_ini_entry *entry, zend_string *new_value, void *mh_arg1, void *mh_arg2, void *mh_arg3, int stage TSRMLS_DC)
#define ZEND_INI_DISP(name) void name(zend_ini_entry *ini_entry, int type)
struct _zend_ini_entry {
int module_number;
int modifiable;
char *name; // TODO: convert into zend_string ???
uint name_length;
typedef struct _zend_ini_entry_def {
const char *name;
ZEND_INI_MH((*on_modify));
void *mh_arg1;
void *mh_arg2;
void *mh_arg3;
const char *value;
void (*displayer)(zend_ini_entry *ini_entry, int type);
int modifiable;
char *value; // TODO: convert into zend_string ???
uint name_length;
uint value_length;
} zend_ini_entry_def;
struct _zend_ini_entry {
zend_string *name;
ZEND_INI_MH((*on_modify));
void *mh_arg1;
void *mh_arg2;
void *mh_arg3;
zend_string *value;
zend_string *orig_value;
void (*displayer)(zend_ini_entry *ini_entry, int type);
int modifiable;
char *orig_value; // TODO: convert into zend_string ???
uint orig_value_length;
int orig_modifiable;
int modified;
void (*displayer)(zend_ini_entry *ini_entry, int type);
int module_number;
};
BEGIN_EXTERN_C()
@@ -61,11 +70,13 @@ ZEND_API int zend_copy_ini_directives(TSRMLS_D);
ZEND_API void zend_ini_sort_entries(TSRMLS_D);
ZEND_API int zend_register_ini_entries(const zend_ini_entry *ini_entry, int module_number TSRMLS_DC);
ZEND_API int zend_register_ini_entries(const zend_ini_entry_def *ini_entry, int module_number TSRMLS_DC);
ZEND_API void zend_unregister_ini_entries(int module_number TSRMLS_DC);
ZEND_API void zend_ini_refresh_caches(int stage TSRMLS_DC);
ZEND_API int zend_alter_ini_entry(zend_string *name, char *new_value, uint new_value_length, int modify_type, int stage);
ZEND_API int zend_alter_ini_entry_ex(zend_string *name, char *new_value, uint new_value_length, int modify_type, int stage, int force_change TSRMLS_DC);
ZEND_API int zend_alter_ini_entry(zend_string *name, zend_string *new_value, int modify_type, int stage);
ZEND_API int zend_alter_ini_entry_ex(zend_string *name, zend_string *new_value, int modify_type, int stage, int force_change TSRMLS_DC);
ZEND_API int zend_alter_ini_entry_chars(zend_string *name, const char *value, size_t value_length, int modify_type, int stage);
ZEND_API int zend_alter_ini_entry_chars_ex(zend_string *name, const char *value, size_t value_length, int modify_type, int stage, int force_change TSRMLS_DC);
ZEND_API int zend_restore_ini_entry(zend_string *name, int stage);
ZEND_API void display_ini_entries(zend_module_entry *module);
@@ -81,11 +92,11 @@ ZEND_API ZEND_INI_DISP(zend_ini_color_displayer_cb);
ZEND_API ZEND_INI_DISP(display_link_numbers);
END_EXTERN_C()
#define ZEND_INI_BEGIN() static const zend_ini_entry ini_entries[] = {
#define ZEND_INI_END() { 0, 0, NULL, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0, 0, 0, NULL } };
#define ZEND_INI_BEGIN() static const zend_ini_entry_def ini_entries[] = {
#define ZEND_INI_END() { NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0} };
#define ZEND_INI_ENTRY3_EX(name, default_value, modifiable, on_modify, arg1, arg2, arg3, displayer) \
{ 0, modifiable, name, sizeof(name)-1, on_modify, arg1, arg2, arg3, default_value, sizeof(default_value)-1, NULL, 0, 0, 0, displayer },
{ name, on_modify, arg1, arg2, arg3, default_value, displayer, modifiable, sizeof(name)-1, sizeof(default_value)-1 },
#define ZEND_INI_ENTRY3(name, default_value, modifiable, on_modify, arg1, arg2, arg3) \
ZEND_INI_ENTRY3_EX(name, default_value, modifiable, on_modify, arg1, arg2, arg3, NULL)

View File

@@ -141,12 +141,12 @@ static void zend_ini_get_constant(zval *result, zval *name TSRMLS_DC)
*/
static void zend_ini_get_var(zval *result, zval *name TSRMLS_DC)
{
zval curval;
zval *curval;
char *envvar;
/* Fetch configuration option value */
if (zend_get_configuration_directive(Z_STRVAL_P(name), Z_STRLEN_P(name), &curval) == SUCCESS) {
ZVAL_PSTRINGL(result, Z_STRVAL(curval), Z_STRLEN(curval));
if ((curval = zend_get_configuration_directive(Z_STR_P(name))) != NULL) {
ZVAL_PSTRINGL(result, Z_STRVAL_P(curval), Z_STRLEN_P(curval));
/* ..or if not found, try ENV */
} else if ((envvar = zend_getenv(Z_STRVAL_P(name), Z_STRLEN_P(name) TSRMLS_CC)) != NULL ||
(envvar = getenv(Z_STRVAL_P(name))) != NULL) {
@@ -264,6 +264,7 @@ ZEND_API int zend_parse_ini_string(char *str, zend_bool unbuffered_errors, int s
%token TC_QUOTED_STRING
%token BOOL_TRUE
%token BOOL_FALSE
%token NULL_NULL
%token END_OF_LINE
%token '=' ':' ',' '.' '"' '\'' '^' '+' '-' '/' '*' '%' '$' '~' '<' '>' '?' '@' '{' '}'
%left '|' '&' '^'
@@ -290,7 +291,7 @@ statement:
#endif
ZEND_INI_PARSER_CB(&$1, &$3, NULL, ZEND_INI_PARSER_ENTRY, ZEND_INI_PARSER_ARG TSRMLS_CC);
zend_string_release(Z_STR($1));
zend_string_release(Z_STR($3));
zval_ptr_dtor(&$3);
}
| TC_OFFSET option_offset ']' '=' string_or_value {
#if DEBUG_CFG_PARSER
@@ -299,7 +300,7 @@ statement:
ZEND_INI_PARSER_CB(&$1, &$5, &$2, ZEND_INI_PARSER_POP_ENTRY, ZEND_INI_PARSER_ARG TSRMLS_CC);
zend_string_release(Z_STR($1));
zend_string_release(Z_STR($2));
zend_string_release(Z_STR($5));
zval_ptr_dtor(&$5);
}
| TC_LABEL { ZEND_INI_PARSER_CB(&$1, NULL, NULL, ZEND_INI_PARSER_ENTRY, ZEND_INI_PARSER_ARG TSRMLS_CC); zend_string_release(Z_STR($1)); }
| END_OF_LINE
@@ -314,6 +315,7 @@ string_or_value:
expr { $$ = $1; }
| BOOL_TRUE { $$ = $1; }
| BOOL_FALSE { $$ = $1; }
| NULL_NULL { $$ = $1; }
| END_OF_LINE { zend_ini_init_string(&$$); }
;

File diff suppressed because it is too large Load Diff

View File

@@ -25,6 +25,7 @@
/* Scanner modes */
#define ZEND_INI_SCANNER_NORMAL 0 /* Normal mode. [DEFAULT] */
#define ZEND_INI_SCANNER_RAW 1 /* Raw mode. Option values are not parsed */
#define ZEND_INI_SCANNER_TYPED 2 /* Typed mode. */
BEGIN_EXTERN_C()
int zend_ini_scanner_get_lineno(TSRMLS_D);

View File

@@ -24,6 +24,7 @@
#include <errno.h>
#include "zend.h"
#include "zend_API.h"
#include "zend_globals.h"
#include <zend_ini_parser.h>
#include "zend_ini_scanner.h"
@@ -135,9 +136,55 @@ ZEND_API zend_ini_scanner_globals ini_scanner_globals;
ZVAL_NEW_STR(retval, zend_string_init(str, len, 1))
#define RETURN_TOKEN(type, str, len) { \
zend_ini_copy_value(ini_lval, str, len); \
return type; \
#define RETURN_TOKEN(type, str, len) { \
if (SCNG(scanner_mode) == ZEND_INI_SCANNER_TYPED) { \
zend_ini_copy_typed_value(ini_lval, type, str, len); \
} else { \
zend_ini_copy_value(ini_lval, str, len); \
} \
return type; \
}
static inline int convert_to_number(zval *retval, const char *str, const int str_len)
{
zend_uchar type;
int overflow;
zend_long lval;
double dval;
if ((type = is_numeric_string_ex(str, str_len, &lval, &dval, 0, &overflow)) != 0) {
if (type == IS_LONG) {
ZVAL_LONG(retval, lval);
return SUCCESS;
} else if (type == IS_DOUBLE && !overflow) {
ZVAL_DOUBLE(retval, dval);
return SUCCESS;
}
}
return FAILURE;
}
static void zend_ini_copy_typed_value(zval *retval, const int type, const char *str, int len)
{
switch (type) {
case BOOL_FALSE:
case BOOL_TRUE:
ZVAL_BOOL(retval, type == BOOL_TRUE);
break;
case NULL_NULL:
ZVAL_NULL(retval);
break;
case TC_NUMBER:
if (convert_to_number(retval, str, len) == SUCCESS) {
break;
}
/* intentional fall-through */
default:
zend_ini_copy_value(retval, str, len);
}
}
static void _yy_push_state(int new_state TSRMLS_DC)
@@ -169,7 +216,7 @@ static void yy_scan_buffer(char *str, unsigned int len TSRMLS_DC)
static int init_ini_scanner(int scanner_mode, zend_file_handle *fh TSRMLS_DC)
{
/* Sanity check */
if (scanner_mode != ZEND_INI_SCANNER_NORMAL && scanner_mode != ZEND_INI_SCANNER_RAW) {
if (scanner_mode != ZEND_INI_SCANNER_NORMAL && scanner_mode != ZEND_INI_SCANNER_RAW && scanner_mode != ZEND_INI_SCANNER_TYPED) {
zend_error(E_WARNING, "Invalid scanner mode");
return FAILURE;
}
@@ -419,10 +466,14 @@ SECTION_VALUE_CHARS ([^$\n\r;"'\]\\]|("\\"{ANY_CHAR})|{LITERAL_DOLLAR})
RETURN_TOKEN(BOOL_TRUE, "1", 1);
}
<INITIAL,ST_VALUE>("false"|"off"|"no"|"none"|"null"){TABS_AND_SPACES}* { /* FALSE value (when used outside option value/offset this causes parse error!)*/
<INITIAL,ST_VALUE>("false"|"off"|"no"|"none"){TABS_AND_SPACES}* { /* FALSE value (when used outside option value/offset this causes parse error!)*/
RETURN_TOKEN(BOOL_FALSE, "", 0);
}
<INITIAL,ST_VALUE>("null"){TABS_AND_SPACES}* {
RETURN_TOKEN(NULL_NULL, "", 0);
}
<INITIAL>{LABEL} { /* Get option name */
/* Eat leading whitespace */
EAT_LEADING_WHITESPACE();

View File

@@ -325,7 +325,8 @@ static int zend_implement_traversable(zend_class_entry *interface, zend_class_en
/* {{{ zend_implement_aggregate */
static int zend_implement_aggregate(zend_class_entry *interface, zend_class_entry *class_type TSRMLS_DC)
{
int i, t = -1;
uint32_t i;
int t = -1;
if (class_type->get_iterator) {
if (class_type->type == ZEND_INTERNAL_CLASS) {
@@ -406,7 +407,7 @@ static int zend_implement_arrayaccess(zend_class_entry *interface, zend_class_en
/* }}}*/
/* {{{ zend_user_serialize */
ZEND_API int zend_user_serialize(zval *object, unsigned char **buffer, uint32_t *buf_len, zend_serialize_data *data TSRMLS_DC)
ZEND_API int zend_user_serialize(zval *object, unsigned char **buffer, size_t *buf_len, zend_serialize_data *data TSRMLS_DC)
{
zend_class_entry * ce = Z_OBJCE_P(object);
zval retval;
@@ -443,7 +444,7 @@ ZEND_API int zend_user_serialize(zval *object, unsigned char **buffer, uint32_t
/* }}} */
/* {{{ zend_user_unserialize */
ZEND_API int zend_user_unserialize(zval *object, zend_class_entry *ce, const unsigned char *buf, uint32_t buf_len, zend_unserialize_data *data TSRMLS_DC)
ZEND_API int zend_user_unserialize(zval *object, zend_class_entry *ce, const unsigned char *buf, size_t buf_len, zend_unserialize_data *data TSRMLS_DC)
{
zval zdata;
@@ -463,7 +464,7 @@ ZEND_API int zend_user_unserialize(zval *object, zend_class_entry *ce, const uns
}
/* }}} */
ZEND_API int zend_class_serialize_deny(zval *object, unsigned char **buffer, uint32_t *buf_len, zend_serialize_data *data TSRMLS_DC) /* {{{ */
ZEND_API int zend_class_serialize_deny(zval *object, unsigned char **buffer, size_t *buf_len, zend_serialize_data *data TSRMLS_DC) /* {{{ */
{
zend_class_entry *ce = Z_OBJCE_P(object);
zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Serialization of '%s' is not allowed", ce->name->val);
@@ -471,7 +472,7 @@ ZEND_API int zend_class_serialize_deny(zval *object, unsigned char **buffer, uin
}
/* }}} */
ZEND_API int zend_class_unserialize_deny(zval *object, zend_class_entry *ce, const unsigned char *buf, uint32_t buf_len, zend_unserialize_data *data TSRMLS_DC) /* {{{ */
ZEND_API int zend_class_unserialize_deny(zval *object, zend_class_entry *ce, const unsigned char *buf, size_t buf_len, zend_unserialize_data *data TSRMLS_DC) /* {{{ */
{
zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Unserialization of '%s' is not allowed", ce->name->val);
return FAILURE;

View File

@@ -61,11 +61,11 @@ ZEND_API zend_object_iterator *zend_user_it_get_new_iterator(zend_class_entry *c
ZEND_API void zend_register_interfaces(TSRMLS_D);
ZEND_API int zend_user_serialize(zval *object, unsigned char **buffer, uint32_t *buf_len, zend_serialize_data *data TSRMLS_DC);
ZEND_API int zend_user_unserialize(zval *object, zend_class_entry *ce, const unsigned char *buf, uint32_t buf_len, zend_unserialize_data *data TSRMLS_DC);
ZEND_API int zend_user_serialize(zval *object, unsigned char **buffer, size_t *buf_len, zend_serialize_data *data TSRMLS_DC);
ZEND_API int zend_user_unserialize(zval *object, zend_class_entry *ce, const unsigned char *buf, size_t buf_len, zend_unserialize_data *data TSRMLS_DC);
ZEND_API int zend_class_serialize_deny(zval *object, unsigned char **buffer, uint32_t *buf_len, zend_serialize_data *data TSRMLS_DC);
ZEND_API int zend_class_unserialize_deny(zval *object, zend_class_entry *ce, const unsigned char *buf, uint32_t buf_len, zend_unserialize_data *data TSRMLS_DC);
ZEND_API int zend_class_serialize_deny(zval *object, unsigned char **buffer, size_t *buf_len, zend_serialize_data *data TSRMLS_DC);
ZEND_API int zend_class_unserialize_deny(zval *object, zend_class_entry *ce, const unsigned char *buf, size_t buf_len, zend_unserialize_data *data TSRMLS_DC);
END_EXTERN_C()

View File

@@ -84,29 +84,13 @@ ZEND_API void zend_iterator_dtor(zend_object_iterator *iter TSRMLS_DC)
zend_objects_store_del(&iter->std TSRMLS_CC);
}
ZEND_API enum zend_object_iterator_kind zend_iterator_unwrap(
zval *array_ptr, zend_object_iterator **iter TSRMLS_DC)
ZEND_API zend_object_iterator* zend_iterator_unwrap(zval *array_ptr TSRMLS_DC)
{
switch (Z_TYPE_P(array_ptr)) {
case IS_OBJECT:
if (Z_OBJ_HT_P(array_ptr) == &iterator_object_handlers) {
*iter = (zend_object_iterator *)Z_OBJ_P(array_ptr);
return ZEND_ITER_OBJECT;
}
if (Z_OBJPROP_P(array_ptr)) {
return ZEND_ITER_PLAIN_OBJECT;
}
return ZEND_ITER_INVALID;
case IS_ARRAY:
if (Z_ARRVAL_P(array_ptr)) {
return ZEND_ITER_PLAIN_ARRAY;
}
return ZEND_ITER_INVALID;
default:
return ZEND_ITER_INVALID;
if (Z_TYPE_P(array_ptr) &&
Z_OBJ_HT_P(array_ptr) == &iterator_object_handlers) {
return (zend_object_iterator *)Z_OBJ_P(array_ptr);
}
return NULL;
}
/*

View File

@@ -71,16 +71,9 @@ typedef struct _zend_class_iterator_funcs {
union _zend_function *zf_rewind;
} zend_class_iterator_funcs;
enum zend_object_iterator_kind {
ZEND_ITER_INVALID,
ZEND_ITER_PLAIN_ARRAY,
ZEND_ITER_PLAIN_OBJECT,
ZEND_ITER_OBJECT
};
BEGIN_EXTERN_C()
/* given a zval, returns stuff that can be used to iterate it. */
ZEND_API enum zend_object_iterator_kind zend_iterator_unwrap(zval *array_ptr, zend_object_iterator **iter TSRMLS_DC);
ZEND_API zend_object_iterator* zend_iterator_unwrap(zval *array_ptr TSRMLS_DC);
/* given an iterator, wrap it up as a zval for use by the engine opcodes */
ZEND_API void zend_iterator_init(zend_object_iterator *iter TSRMLS_DC);

File diff suppressed because it is too large Load Diff

View File

@@ -126,7 +126,7 @@ BEGIN_EXTERN_C()
static size_t encoding_filter_script_to_internal(unsigned char **to, size_t *to_length, const unsigned char *from, size_t from_length TSRMLS_DC)
{
const zend_encoding *internal_encoding = zend_multibyte_get_internal_encoding(TSRMLS_C);
assert(internal_encoding && zend_multibyte_check_lexer_compatibility(internal_encoding));
ZEND_ASSERT(internal_encoding);
return zend_multibyte_encoding_converter(to, to_length, from, from_length, internal_encoding, LANG_SCNG(script_encoding) TSRMLS_CC);
}
@@ -144,7 +144,7 @@ LANG_SCNG(script_encoding), zend_multibyte_encoding_utf8 TSRMLS_CC);
static size_t encoding_filter_intermediate_to_internal(unsigned char **to, size_t *to_length, const unsigned char *from, size_t from_length TSRMLS_DC)
{
const zend_encoding *internal_encoding = zend_multibyte_get_internal_encoding(TSRMLS_C);
assert(internal_encoding && zend_multibyte_check_lexer_compatibility(internal_encoding));
ZEND_ASSERT(internal_encoding);
return zend_multibyte_encoding_converter(to, to_length, from, from_length,
internal_encoding, zend_multibyte_encoding_utf8 TSRMLS_CC);
}
@@ -556,7 +556,6 @@ ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type TSR
zend_lex_state original_lex_state;
zend_op_array *op_array = (zend_op_array *) emalloc(sizeof(zend_op_array));
zend_op_array *original_active_op_array = CG(active_op_array);
zend_op_array *retval=NULL;
int compiler_result;
zend_bool compilation_successful=0;
zval retval_zv;
@@ -566,8 +565,6 @@ ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type TSR
zend_save_lexical_state(&original_lex_state TSRMLS_CC);
retval = op_array; /* success oriented */
if (open_file_for_scanning(file_handle TSRMLS_CC)==FAILURE) {
if (type==ZEND_REQUIRE) {
zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, file_handle->filename TSRMLS_CC);
@@ -596,18 +593,17 @@ ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type TSR
compilation_successful=1;
}
if (retval) {
CG(active_op_array) = original_active_op_array;
if (compilation_successful) {
pass_two(op_array TSRMLS_CC);
zend_release_labels(0 TSRMLS_CC);
} else {
efree_size(op_array, sizeof(zend_op_array));
retval = NULL;
}
CG(active_op_array) = original_active_op_array;
if (compilation_successful) {
pass_two(op_array TSRMLS_CC);
zend_release_labels(0 TSRMLS_CC);
} else {
efree_size(op_array, sizeof(zend_op_array));
op_array = NULL;
}
zend_restore_lexical_state(&original_lex_state TSRMLS_CC);
return retval;
return op_array;
}
@@ -847,7 +843,7 @@ ZEND_API void zend_multibyte_yyinput_again(zend_encoding_filter old_input_filter
SCNG(yy_cursor) = new_yy_start + (SCNG(yy_cursor) - SCNG(yy_start));
SCNG(yy_marker) = new_yy_start + (SCNG(yy_marker) - SCNG(yy_start));
SCNG(yy_text) = new_yy_start + (SCNG(yy_text) - SCNG(yy_start));
SCNG(yy_limit) = new_yy_start + (SCNG(yy_limit) - SCNG(yy_start));
SCNG(yy_limit) = new_yy_start + length;
SCNG(yy_start) = new_yy_start;
}
@@ -1764,6 +1760,7 @@ inline_html:
/* Invalid rule to return a more explicit parse error with proper line number */
yyless(0);
yy_pop_state(TSRMLS_C);
ZVAL_NULL(zendlval);
return T_ENCAPSED_AND_WHITESPACE;
}
@@ -1878,6 +1875,7 @@ inline_html:
/* Unclosed single quotes; treat similar to double quotes, but without a separate token
* for ' (unrecognized by parser), instead of old flex fallback to "Unexpected character..."
* rule, which continued in ST_IN_SCRIPTING state after the quote */
ZVAL_NULL(zendlval);
return T_ENCAPSED_AND_WHITESPACE;
}
}

View File

@@ -126,32 +126,26 @@ ZEND_API void zend_llist_clean(zend_llist *l)
}
ZEND_API void *zend_llist_remove_tail(zend_llist *l)
ZEND_API void zend_llist_remove_tail(zend_llist *l)
{
zend_llist_element *old_tail;
void *data;
if ((old_tail = l->tail)) {
if (old_tail->prev) {
old_tail->prev->next = NULL;
} else {
l->head = NULL;
}
data = old_tail->data;
l->tail = old_tail->prev;
if (l->dtor) {
l->dtor(data);
}
pefree(old_tail, l->persistent);
--l->count;
return data;
zend_llist_element *old_tail = l->tail;
if (!old_tail) {
return;
}
return NULL;
if (old_tail->prev) {
old_tail->prev->next = NULL;
} else {
l->head = NULL;
}
l->tail = old_tail->prev;
--l->count;
if (l->dtor) {
l->dtor(old_tail->data);
}
pefree(old_tail, l->persistent);
}

View File

@@ -53,7 +53,7 @@ ZEND_API void zend_llist_prepend_element(zend_llist *l, void *element);
ZEND_API void zend_llist_del_element(zend_llist *l, void *element, int (*compare)(void *element1, void *element2));
ZEND_API void zend_llist_destroy(zend_llist *l);
ZEND_API void zend_llist_clean(zend_llist *l);
ZEND_API void *zend_llist_remove_tail(zend_llist *l);
ZEND_API void zend_llist_remove_tail(zend_llist *l);
ZEND_API void zend_llist_copy(zend_llist *dst, zend_llist *src);
ZEND_API void zend_llist_apply(zend_llist *l, llist_apply_func_t func TSRMLS_DC);
ZEND_API void zend_llist_apply_with_del(zend_llist *l, int (*func)(void *data));

View File

@@ -52,8 +52,8 @@ typedef int32_t zend_off_t;
# define ZEND_LONG_MAX INT32_MAX
# define ZEND_LONG_MIN INT32_MIN
# define ZEND_ULONG_MAX UINT32_MAX
# define Z_L(i) i
# define Z_UL(i) i
# define Z_L(i) INT32_C(i)
# define Z_UL(i) UINT32_C(i)
# define SIZEOF_ZEND_LONG 4
#endif
@@ -110,6 +110,17 @@ typedef int32_t zend_off_t;
# define ZEND_ABS abs
#endif
#if SIZEOF_ZEND_LONG == 4
# define MAX_LENGTH_OF_LONG 11
# define LONG_MIN_DIGITS "2147483648"
#elif SIZEOF_ZEND_LONG == 8
# define MAX_LENGTH_OF_LONG 20
# define LONG_MIN_DIGITS "9223372036854775808"
#else
# error "Unknown SIZEOF_ZEND_LONG"
#endif
static const char long_min_digits[] = LONG_MIN_DIGITS;
#endif /* ZEND_LONG_H */

View File

@@ -19,6 +19,9 @@
/* $Id$ */
#ifndef ZEND_MULTIPLY_H
#define ZEND_MULTIPLY_H
#if defined(__i386__) && defined(__GNUC__)
#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
@@ -108,3 +111,138 @@
} while (0)
#endif
#if defined(__GNUC__) && (defined(__native_client__) || defined(i386))
static zend_always_inline size_t zend_safe_address(size_t nmemb, size_t size, size_t offset, int *overflow)
{
size_t res = nmemb;
zend_ulong m_overflow = 0;
__asm__ ("mull %3\n\taddl %4,%0\n\tadcl $0,%1"
: "=&a"(res), "=&d" (m_overflow)
: "%0"(res),
"rm"(size),
"rm"(offset));
if (UNEXPECTED(m_overflow)) {
*overflow = 1;
return 0;
}
*overflow = 0;
return res;
}
#elif defined(__GNUC__) && defined(__x86_64__)
static zend_always_inline size_t zend_safe_address(size_t nmemb, size_t size, size_t offset, int *overflow)
{
size_t res = nmemb;
zend_ulong m_overflow = 0;
#ifdef __ILP32__ /* x32 */
# define LP_SUFF "l"
#else /* amd64 */
# define LP_SUFF "q"
#endif
__asm__ ("mul" LP_SUFF " %3\n\t"
"add %4,%0\n\t"
"adc $0,%1"
: "=&a"(res), "=&d" (m_overflow)
: "%0"(res),
"rm"(size),
"rm"(offset));
#undef LP_SUFF
if (UNEXPECTED(m_overflow)) {
*overflow = 1;
return 0;
}
*overflow = 0;
return res;
}
#elif defined(__GNUC__) && defined(__arm__)
static zend_always_inline size_t zend_safe_address(size_t nmemb, size_t size, size_t offset, int *overflow)
{
size_t res;
zend_ulong m_overflow;
__asm__ ("umlal %0,%1,%2,%3"
: "=r"(res), "=r"(m_overflow)
: "r"(nmemb),
"r"(size),
"0"(offset),
"1"(0));
if (UNEXPECTED(m_overflow)) {
*overflow = 1;
return 0;
}
*overflow = 0;
return res;
}
#elif defined(__GNUC__) && defined(__aarch64__)
static zend_always_inline size_t zend_safe_address(size_t nmemb, size_t size, size_t offset, int *overflow)
{
size_t res;
zend_ulong m_overflow;
__asm__ ("mul %0,%2,%3\n\tumulh %1,%2,%3\n\tadds %0,%0,%4\n\tadc %1,%1,xzr"
: "=&r"(res), "=&r"(m_overflow)
: "r"(nmemb),
"r"(size),
"r"(offset));
if (UNEXPECTED(m_overflow)) {
*overflow = 1;
return 0;
}
*overflow = 0;
return res;
}
#elif SIZEOF_SIZE_T == 4 && defined(HAVE_ZEND_LONG64)
static zend_always_inline size_t zend_safe_address(size_t nmemb, size_t size, size_t offset, int *overflow)
{
zend_ulong64 res = (zend_ulong64)nmemb * (zend_ulong64)size + (zend_ulong64)offset;
if (UNEXPECTED(res > (zend_ulong64)0xFFFFFFFFL)) {
*overflow = 1;
return 0;
}
*overflow = 0;
return (size_t) res;
}
#else
static zend_always_inline size_t zend_safe_address(size_t nmemb, size_t size, size_t offset, int *overflow)
{
size_t res = nmemb * size + offset;
double _d = (double)nmemb * (double)size + (double)offset;
double _delta = (double)res - _d;
if (UNEXPECTED((_d + _delta ) != _d)) {
*overflow = 1;
return 0;
}
*overflow = 0;
return res;
}
#endif
#endif /* ZEND_MULTIPLY_H */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* indent-tabs-mode: t
* End:
*/

View File

@@ -385,9 +385,9 @@ static zend_always_inline struct _zend_property_info *zend_get_property_info_qui
}
/* }}} */
ZEND_API struct _zend_property_info *zend_get_property_info(zend_class_entry *ce, zval *member, int silent TSRMLS_DC) /* {{{ */
ZEND_API struct _zend_property_info *zend_get_property_info(zend_class_entry *ce, zend_string *member, int silent TSRMLS_DC) /* {{{ */
{
return zend_get_property_info_quick(ce, Z_STR_P(member), silent, NULL TSRMLS_CC);
return zend_get_property_info_quick(ce, member, silent, NULL TSRMLS_CC);
}
/* }}} */
@@ -397,10 +397,10 @@ ZEND_API int zend_check_property_access(zend_object *zobj, zend_string *prop_inf
const char *class_name = NULL;
const char *prop_name;
zend_string *member;
int prop_name_len;
size_t prop_name_len;
if (prop_info_name->val[0] == 0) {
zend_unmangle_property_name_ex(prop_info_name->val, prop_info_name->len, &class_name, &prop_name, &prop_name_len);
zend_unmangle_property_name_ex(prop_info_name, &class_name, &prop_name, &prop_name_len);
member = zend_string_init(prop_name, prop_name_len, 0);
} else {
member = zend_string_copy(prop_info_name);
@@ -434,10 +434,12 @@ static zend_long *zend_get_property_guard(zend_object *zobj, zend_property_info
info.name = Z_STR_P(member);
} else if(property_info->name->val[0] == '\0'){
const char *class_name = NULL, *prop_name = NULL;
zend_unmangle_property_name(property_info->name->val, property_info->name->len, &class_name, &prop_name);
size_t prop_name_len;
zend_unmangle_property_name_ex(property_info->name, &class_name,
&prop_name, &prop_name_len);
if (class_name) {
/* use unmangled name for protected properties */
str = info.name = zend_string_init(prop_name, strlen(prop_name), 0);
str = info.name = zend_string_init(prop_name, prop_name_len, 0);
property_info = &info;
}
}
@@ -659,12 +661,12 @@ found:
}
}
} else if (EXPECTED(property_info != NULL)) {
zval tmp;
write_std_property:
/* if we assign referenced variable, we should separate it */
if (Z_REFCOUNTED_P(value)) {
if (Z_ISREF_P(value)) {
zval tmp;
/* if we assign referenced variable, we should separate it */
ZVAL_DUP(&tmp, Z_REFVAL_P(value));
value = &tmp;
} else {

View File

@@ -159,7 +159,7 @@ ZEND_API union _zend_function *zend_std_get_static_method(zend_class_entry *ce,
ZEND_API zval *zend_std_get_static_property(zend_class_entry *ce, zend_string *property_name, zend_bool silent, void **cache_slot TSRMLS_DC);
ZEND_API zend_bool zend_std_unset_static_property(zend_class_entry *ce, zend_string *property_name, void **cache_slot TSRMLS_DC);
ZEND_API union _zend_function *zend_std_get_constructor(zend_object *object TSRMLS_DC);
ZEND_API struct _zend_property_info *zend_get_property_info(zend_class_entry *ce, zval *member, int silent TSRMLS_DC);
ZEND_API struct _zend_property_info *zend_get_property_info(zend_class_entry *ce, zend_string *member, int silent TSRMLS_DC);
ZEND_API HashTable *zend_std_get_properties(zval *object TSRMLS_DC);
ZEND_API HashTable *zend_std_get_debug_info(zval *object, int *is_temp TSRMLS_DC);
ZEND_API int zend_std_cast_object_tostring(zval *readobj, zval *writeobj, int type TSRMLS_DC);

View File

@@ -154,7 +154,7 @@ ZEND_API void zend_objects_clone_members(zend_object *new_object, zend_object *o
if (!new_object->properties) {
ALLOC_HASHTABLE(new_object->properties);
zend_hash_init(new_object->properties, 8, NULL, ZVAL_PTR_DTOR, 0);
zend_hash_init(new_object->properties, zend_hash_num_elements(old_object->properties), NULL, ZVAL_PTR_DTOR, 0);
}
ZEND_HASH_FOREACH_KEY_VAL(old_object->properties, num_key, key, prop) {

View File

@@ -343,7 +343,7 @@ ZEND_API void destroy_op_array(zend_op_array *op_array TSRMLS_DC)
if (literal) {
end = literal + op_array->last_literal;
while (literal < end) {
zval_dtor(literal);
zval_ptr_dtor_nogc(literal);
literal++;
}
efree(op_array->literals);
@@ -444,7 +444,7 @@ static void zend_extension_op_array_handler(zend_extension *extension, zend_op_a
static void zend_check_finally_breakout(zend_op_array *op_array, uint32_t op_num, uint32_t dst_num TSRMLS_DC)
{
uint32_t i;
int i;
for (i = 0; i < op_array->last_try_catch; i++) {
if ((op_num < op_array->try_catch_array[i].finally_op ||
@@ -738,7 +738,6 @@ ZEND_API int pass_two(zend_op_array *op_array TSRMLS_DC)
case ZEND_JMPZ_EX:
case ZEND_JMPNZ_EX:
case ZEND_JMP_SET:
case ZEND_JMP_SET_VAR:
case ZEND_NEW:
case ZEND_FE_RESET:
case ZEND_FE_FETCH:

View File

@@ -135,52 +135,6 @@ ZEND_API zend_long zend_atol(const char *str, int str_len) /* {{{ */
}
/* }}} */
ZEND_API double zend_string_to_double(const char *number, uint32_t length) /* {{{ */
{
double divisor = 10.0;
double result = 0.0;
double exponent;
const char *end = number+length;
const char *digit = number;
if (!length) {
return result;
}
while (digit < end) {
if ((*digit <= '9' && *digit >= '0')) {
result *= 10;
result += *digit - '0';
} else if (*digit == '.') {
digit++;
break;
} else if (toupper(*digit) == 'E') {
exponent = (double) atoi(digit+1);
result *= pow(10.0, exponent);
return result;
} else {
return result;
}
digit++;
}
while (digit < end) {
if ((*digit <= '9' && *digit >= '0')) {
result += (*digit - '0') / divisor;
divisor *= 10;
} else if (toupper(*digit) == 'E') {
exponent = (double) atoi(digit+1);
result *= pow(10.0, exponent);
return result;
} else {
return result;
}
digit++;
}
return result;
}
/* }}} */
ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC) /* {{{ */
{
try_again:
@@ -405,7 +359,7 @@ ZEND_API void convert_to_long_base(zval *op, int base) /* {{{ */
{
zend_string *str = Z_STR_P(op);
ZVAL_LONG(op, strtol(str->val, NULL, base));
ZVAL_LONG(op, ZEND_STRTOL(str->val, NULL, base));
zend_string_release(str);
}
break;
@@ -586,6 +540,7 @@ ZEND_API void _convert_to_cstring(zval *op ZEND_FILE_LINE_DC) /* {{{ */
ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC) /* {{{ */
{
switch (Z_TYPE_P(op)) {
case IS_UNDEF:
case IS_NULL:
case IS_FALSE: {
TSRMLS_FETCH();
@@ -868,6 +823,7 @@ ZEND_API zend_string *_zval_get_string_func(zval *op TSRMLS_DC) /* {{{ */
{
try_again:
switch (Z_TYPE_P(op)) {
case IS_UNDEF:
case IS_NULL:
case IS_FALSE:
return STR_EMPTY_ALLOC();
@@ -1575,29 +1531,33 @@ ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{
op2 = &op2_copy;
}
if (result==op1 && !IS_INTERNED(Z_STR_P(op1))) { /* special case, perform operations on result */
{
size_t op1_len = Z_STRLEN_P(op1);
size_t op2_len = Z_STRLEN_P(op2);
size_t res_len = op1_len + op2_len;
size_t result_len = op1_len + op2_len;
zend_string *result_str;
if (Z_STRLEN_P(result) < 0 || (size_t) (op1_len + op2_len) < 0) {
ZVAL_EMPTY_STRING(result);
zend_error(E_ERROR, "String size overflow");
if (op1_len > SIZE_MAX - op2_len) {
zend_error_noreturn(E_ERROR, "String size overflow");
}
Z_STR_P(result) = zend_string_realloc(Z_STR_P(result), res_len, 0 );
Z_TYPE_INFO_P(result) = IS_STRING_EX;
memcpy(Z_STRVAL_P(result) + op1_len, Z_STRVAL_P(op2), op2_len);
Z_STRVAL_P(result)[res_len]=0;
} else {
size_t length = Z_STRLEN_P(op1) + Z_STRLEN_P(op2);
zend_string *buf = zend_string_alloc(length, 0);
if (result == op1 && Z_REFCOUNTED_P(result)) {
/* special case, perform operations on result */
result_str = zend_string_realloc(Z_STR_P(result), result_len, 0);
} else {
result_str = zend_string_alloc(result_len, 0);
memcpy(result_str->val, Z_STRVAL_P(op1), op1_len);
}
memcpy(buf->val, Z_STRVAL_P(op1), Z_STRLEN_P(op1));
memcpy(buf->val + Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
buf->val[length] = 0;
ZVAL_NEW_STR(result, buf);
/* This has to happen first to account for the cases where result == op1 == op2 and
* the realloc is done. In this case this line will also update Z_STRVAL_P(op2) to
* point to the new string. The first op2_len bytes of result will still be the same. */
ZVAL_NEW_STR(result, result_str);
memcpy(result_str->val + op1_len, Z_STRVAL_P(op2), op2_len);
result_str->val[result_len] = '\0';
}
if (UNEXPECTED(use_copy1)) {
zval_dtor(op1);
}
@@ -2059,7 +2019,7 @@ static void increment_string(zval *str) /* {{{ */
return;
}
if (IS_INTERNED(Z_STR_P(str))) {
if (!Z_REFCOUNTED_P(str)) {
Z_STR_P(str) = zend_string_init(Z_STRVAL_P(str), Z_STRLEN_P(str), 0);
Z_TYPE_INFO_P(str) = IS_STRING_EX;
} else if (Z_REFCOUNT_P(str) > 1) {
@@ -2070,7 +2030,7 @@ static void increment_string(zval *str) /* {{{ */
}
s = Z_STRVAL_P(str);
while (pos >= 0) {
do {
ch = s[pos];
if (ch >= 'a' && ch <= 'z') {
if (ch == 'z') {
@@ -2106,8 +2066,7 @@ static void increment_string(zval *str) /* {{{ */
if (carry == 0) {
break;
}
pos--;
}
} while (pos-- > 0);
if (carry) {
t = zend_string_alloc(Z_STRLEN_P(str)+1, 0);
@@ -2561,8 +2520,7 @@ ZEND_API void zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_DC) /* {{{ */
ZEND_API zend_string *zend_long_to_str(zend_long num) /* {{{ */
{
char buf[MAX_LENGTH_OF_LONG + 1];
char *res;
_zend_print_signed_to_buf(buf + sizeof(buf) - 1, num, zend_ulong, res);
char *res = zend_print_long_to_buf(buf + sizeof(buf) - 1, num);
return zend_string_init(res, buf + sizeof(buf) - 1 - res, 0);
}
/* }}} */
@@ -2571,6 +2529,143 @@ ZEND_API zend_uchar is_numeric_str_function(const zend_string *str, zend_long *l
return is_numeric_string_ex(str->val, str->len, lval, dval, -1, NULL);
}
ZEND_API zend_uchar _is_numeric_string_ex(const char *str, size_t length, zend_long *lval, double *dval, int allow_errors, int *oflow_info)
{
const char *ptr;
int base = 10, digits = 0, dp_or_e = 0;
double local_dval = 0.0;
zend_uchar type;
if (!length) {
return 0;
}
if (oflow_info != NULL) {
*oflow_info = 0;
}
/* Skip any whitespace
* This is much faster than the isspace() function */
while (*str == ' ' || *str == '\t' || *str == '\n' || *str == '\r' || *str == '\v' || *str == '\f') {
str++;
length--;
}
ptr = str;
if (*ptr == '-' || *ptr == '+') {
ptr++;
}
if (ZEND_IS_DIGIT(*ptr)) {
/* Handle hex numbers
* str is used instead of ptr to disallow signs and keep old behavior */
if (length > 2 && *str == '0' && (str[1] == 'x' || str[1] == 'X')) {
base = 16;
ptr += 2;
}
/* Skip any leading 0s */
while (*ptr == '0') {
ptr++;
}
/* Count the number of digits. If a decimal point/exponent is found,
* it's a double. Otherwise, if there's a dval or no need to check for
* a full match, stop when there are too many digits for a long */
for (type = IS_LONG; !(digits >= MAX_LENGTH_OF_LONG && (dval || allow_errors == 1)); digits++, ptr++) {
check_digits:
if (ZEND_IS_DIGIT(*ptr) || (base == 16 && ZEND_IS_XDIGIT(*ptr))) {
continue;
} else if (base == 10) {
if (*ptr == '.' && dp_or_e < 1) {
goto process_double;
} else if ((*ptr == 'e' || *ptr == 'E') && dp_or_e < 2) {
const char *e = ptr + 1;
if (*e == '-' || *e == '+') {
ptr = e++;
}
if (ZEND_IS_DIGIT(*e)) {
goto process_double;
}
}
}
break;
}
if (base == 10) {
if (digits >= MAX_LENGTH_OF_LONG) {
if (oflow_info != NULL) {
*oflow_info = *str == '-' ? -1 : 1;
}
dp_or_e = -1;
goto process_double;
}
} else if (!(digits < SIZEOF_ZEND_LONG * 2 || (digits == SIZEOF_ZEND_LONG * 2 && ptr[-digits] <= '7'))) {
if (dval) {
local_dval = zend_hex_strtod(str, &ptr);
}
if (oflow_info != NULL) {
*oflow_info = 1;
}
type = IS_DOUBLE;
}
} else if (*ptr == '.' && ZEND_IS_DIGIT(ptr[1])) {
process_double:
type = IS_DOUBLE;
/* If there's a dval, do the conversion; else continue checking
* the digits if we need to check for a full match */
if (dval) {
local_dval = zend_strtod(str, &ptr);
} else if (allow_errors != 1 && dp_or_e != -1) {
dp_or_e = (*ptr++ == '.') ? 1 : 2;
goto check_digits;
}
} else {
return 0;
}
if (ptr != str + length) {
if (!allow_errors) {
return 0;
}
if (allow_errors == -1) {
zend_error(E_NOTICE, "A non well formed numeric value encountered");
}
}
if (type == IS_LONG) {
if (digits == MAX_LENGTH_OF_LONG - 1) {
int cmp = strcmp(&ptr[-digits], long_min_digits);
if (!(cmp < 0 || (cmp == 0 && *str == '-'))) {
if (dval) {
*dval = zend_strtod(str, NULL);
}
if (oflow_info != NULL) {
*oflow_info = *str == '-' ? -1 : 1;
}
return IS_DOUBLE;
}
}
if (lval) {
*lval = ZEND_STRTOL(str, NULL, base);
}
return IS_LONG;
} else {
if (dval) {
*dval = local_dval;
}
return IS_DOUBLE;
}
}
/*
* Local variables:
* tab-width: 4

View File

@@ -129,150 +129,23 @@ static zend_always_inline zend_long zend_dval_to_lval(double d)
* could not be represented as such due to overflow. It writes 1 to oflow_info
* if the integer is larger than ZEND_LONG_MAX and -1 if it's smaller than ZEND_LONG_MIN.
*/
static inline zend_uchar is_numeric_string_ex(const char *str, size_t length, zend_long *lval, double *dval, int allow_errors, int *oflow_info)
ZEND_API zend_uchar _is_numeric_string_ex(const char *str, size_t length, zend_long *lval, double *dval, int allow_errors, int *oflow_info);
static zend_always_inline zend_uchar is_numeric_string_ex(const char *str, size_t length, zend_long *lval, double *dval, int allow_errors, int *oflow_info)
{
const char *ptr;
int base = 10, digits = 0, dp_or_e = 0;
double local_dval = 0.0;
zend_uchar type;
if (!length) {
if (*str > '9') {
return 0;
}
if (oflow_info != NULL) {
*oflow_info = 0;
}
/* Skip any whitespace
* This is much faster than the isspace() function */
while (*str == ' ' || *str == '\t' || *str == '\n' || *str == '\r' || *str == '\v' || *str == '\f') {
str++;
length--;
}
ptr = str;
if (*ptr == '-' || *ptr == '+') {
ptr++;
}
if (ZEND_IS_DIGIT(*ptr)) {
/* Handle hex numbers
* str is used instead of ptr to disallow signs and keep old behavior */
if (length > 2 && *str == '0' && (str[1] == 'x' || str[1] == 'X')) {
base = 16;
ptr += 2;
}
/* Skip any leading 0s */
while (*ptr == '0') {
ptr++;
}
/* Count the number of digits. If a decimal point/exponent is found,
* it's a double. Otherwise, if there's a dval or no need to check for
* a full match, stop when there are too many digits for a long */
for (type = IS_LONG; !(digits >= MAX_LENGTH_OF_LONG && (dval || allow_errors == 1)); digits++, ptr++) {
check_digits:
if (ZEND_IS_DIGIT(*ptr) || (base == 16 && ZEND_IS_XDIGIT(*ptr))) {
continue;
} else if (base == 10) {
if (*ptr == '.' && dp_or_e < 1) {
goto process_double;
} else if ((*ptr == 'e' || *ptr == 'E') && dp_or_e < 2) {
const char *e = ptr + 1;
if (*e == '-' || *e == '+') {
ptr = e++;
}
if (ZEND_IS_DIGIT(*e)) {
goto process_double;
}
}
}
break;
}
if (base == 10) {
if (digits >= MAX_LENGTH_OF_LONG) {
if (oflow_info != NULL) {
*oflow_info = *str == '-' ? -1 : 1;
}
dp_or_e = -1;
goto process_double;
}
} else if (!(digits < SIZEOF_ZEND_LONG * 2 || (digits == SIZEOF_ZEND_LONG * 2 && ptr[-digits] <= '7'))) {
if (dval) {
local_dval = zend_hex_strtod(str, &ptr);
}
if (oflow_info != NULL) {
*oflow_info = 1;
}
type = IS_DOUBLE;
}
} else if (*ptr == '.' && ZEND_IS_DIGIT(ptr[1])) {
process_double:
type = IS_DOUBLE;
/* If there's a dval, do the conversion; else continue checking
* the digits if we need to check for a full match */
if (dval) {
local_dval = zend_strtod(str, &ptr);
} else if (allow_errors != 1 && dp_or_e != -1) {
dp_or_e = (*ptr++ == '.') ? 1 : 2;
goto check_digits;
}
} else {
return 0;
}
if (ptr != str + length) {
if (!allow_errors) {
return 0;
}
if (allow_errors == -1) {
zend_error(E_NOTICE, "A non well formed numeric value encountered");
}
}
if (type == IS_LONG) {
if (digits == MAX_LENGTH_OF_LONG - 1) {
int cmp = strcmp(&ptr[-digits], long_min_digits);
if (!(cmp < 0 || (cmp == 0 && *str == '-'))) {
if (dval) {
*dval = zend_strtod(str, NULL);
}
if (oflow_info != NULL) {
*oflow_info = *str == '-' ? -1 : 1;
}
return IS_DOUBLE;
}
}
if (lval) {
*lval = ZEND_STRTOL(str, NULL, base);
}
return IS_LONG;
} else {
if (dval) {
*dval = local_dval;
}
return IS_DOUBLE;
}
return _is_numeric_string_ex(str, length, lval, dval, allow_errors, oflow_info);
}
static inline zend_uchar is_numeric_string(const char *str, size_t length, zend_long *lval, double *dval, int allow_errors) {
static zend_always_inline zend_uchar is_numeric_string(const char *str, size_t length, zend_long *lval, double *dval, int allow_errors) {
return is_numeric_string_ex(str, length, lval, dval, allow_errors, NULL);
}
ZEND_API zend_uchar is_numeric_str_function(const zend_string *str, zend_long *lval, double *dval);
static inline const char *
static zend_always_inline const char *
zend_memnstr(const char *haystack, const char *needle, size_t needle_len, char *end)
{
const char *p = haystack;
@@ -309,7 +182,7 @@ zend_memnstr(const char *haystack, const char *needle, size_t needle_len, char *
return NULL;
}
static inline const void *zend_memrchr(const void *s, int c, size_t n)
static zend_always_inline const void *zend_memrchr(const void *s, int c, size_t n)
{
register const unsigned char *e;
@@ -367,8 +240,6 @@ ZEND_API int add_string_to_string(zval *result, const zval *op1, const zval *op2
#define convert_to_cstring(op) if (Z_TYPE_P(op) != IS_STRING) { _convert_to_cstring((op) ZEND_FILE_LINE_CC); }
#define convert_to_string(op) if (Z_TYPE_P(op) != IS_STRING) { _convert_to_string((op) ZEND_FILE_LINE_CC); }
ZEND_API double zend_string_to_double(const char *number, uint32_t length);
ZEND_API int zval_is_true(zval *op);
ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_API int numeric_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
@@ -1023,27 +894,26 @@ static zend_always_inline void fast_is_not_identical_function(zval *result, zval
return SUCCESS; \
}
/* input: buf points to the END of the buffer */
#define _zend_print_unsigned_to_buf(buf, num, vartype, result) do { \
char *__p = (buf); \
vartype __num = (num); \
*__p = '\0'; \
do { \
*--__p = (char) (__num % 10) + '0'; \
__num /= 10; \
} while (__num > 0); \
result = __p; \
} while (0)
/* buf points to the END of the buffer */
static zend_always_inline char *zend_print_ulong_to_buf(char *buf, zend_ulong num) {
*buf = '\0';
do {
*--buf = (char) (num % 10) + '0';
num /= 10;
} while (num > 0);
return buf;
}
/* buf points to the END of the buffer */
#define _zend_print_signed_to_buf(buf, num, vartype, result) do { \
if (num < 0) { \
_zend_print_unsigned_to_buf((buf), -(vartype)(num), vartype, (result)); \
*--(result) = '-'; \
} else { \
_zend_print_unsigned_to_buf((buf), (num), vartype, (result)); \
} \
} while (0)
static zend_always_inline char *zend_print_long_to_buf(char *buf, zend_long num) {
if (num < 0) {
char *result = zend_print_ulong_to_buf(buf, ~((zend_ulong) num) + 1);
*--result = '-';
return result;
} else {
return zend_print_ulong_to_buf(buf, num);
}
}
ZEND_API zend_string *zend_long_to_str(zend_long num);

399
Zend/zend_portability.h Normal file
View File

@@ -0,0 +1,399 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 2.00 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.zend.com/license/2_00.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
| Dmitry Stogov <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#ifndef ZEND_PORTABILITY_H
#define ZEND_PORTABILITY_H
#ifdef __cplusplus
#define BEGIN_EXTERN_C() extern "C" {
#define END_EXTERN_C() }
#else
#define BEGIN_EXTERN_C()
#define END_EXTERN_C()
#endif
/*
* general definitions
*/
#ifdef ZEND_WIN32
# include "zend_config.w32.h"
# define ZEND_PATHS_SEPARATOR ';'
#elif defined(NETWARE)
# include <zend_config.h>
# define ZEND_PATHS_SEPARATOR ';'
#elif defined(__riscos__)
# include <zend_config.h>
# define ZEND_PATHS_SEPARATOR ';'
#else
# include <zend_config.h>
# define ZEND_PATHS_SEPARATOR ':'
#endif
#include "../TSRM/TSRM.h"
#include <stdio.h>
#include <assert.h>
#ifdef HAVE_UNIX_H
# include <unix.h>
#endif
#ifdef HAVE_STDARG_H
# include <stdarg.h>
#endif
#ifdef HAVE_DLFCN_H
# include <dlfcn.h>
#endif
#ifdef HAVE_LIMITS_H
# include <limits.h>
#endif
#if HAVE_ALLOCA_H && !defined(_ALLOCA_H)
# include <alloca.h>
#endif
/* Only use this macro if you know for sure that all of the switches values
are covered by its case statements */
#if ZEND_DEBUG
# define EMPTY_SWITCH_DEFAULT_CASE() default: ZEND_ASSERT(0); break;
#elif defined(ZEND_WIN32)
# define EMPTY_SWITCH_DEFAULT_CASE() default: __assume(0); break;
#else
# define EMPTY_SWITCH_DEFAULT_CASE()
#endif
/* all HAVE_XXX test have to be after the include of zend_config above */
#if defined(HAVE_LIBDL) && !defined(ZEND_WIN32)
# ifndef RTLD_LAZY
# define RTLD_LAZY 1 /* Solaris 1, FreeBSD's (2.1.7.1 and older) */
# endif
# ifndef RTLD_GLOBAL
# define RTLD_GLOBAL 0
# endif
# if defined(RTLD_GROUP) && defined(RTLD_WORLD) && defined(RTLD_PARENT)
# define DL_LOAD(libname) dlopen(libname, RTLD_LAZY | RTLD_GLOBAL | RTLD_GROUP | RTLD_WORLD | RTLD_PARENT)
# elif defined(RTLD_DEEPBIND)
# define DL_LOAD(libname) dlopen(libname, RTLD_LAZY | RTLD_GLOBAL | RTLD_DEEPBIND)
# else
# define DL_LOAD(libname) dlopen(libname, RTLD_LAZY | RTLD_GLOBAL)
# endif
# define DL_UNLOAD dlclose
# if defined(DLSYM_NEEDS_UNDERSCORE)
# define DL_FETCH_SYMBOL(h,s) dlsym((h), "_" s)
# else
# define DL_FETCH_SYMBOL dlsym
# endif
# define DL_ERROR dlerror
# define DL_HANDLE void *
# define ZEND_EXTENSIONS_SUPPORT 1
#elif defined(ZEND_WIN32)
# define DL_LOAD(libname) LoadLibrary(libname)
# define DL_FETCH_SYMBOL GetProcAddress
# define DL_UNLOAD FreeLibrary
# define DL_HANDLE HMODULE
# define ZEND_EXTENSIONS_SUPPORT 1
#else
# define DL_HANDLE void *
# define ZEND_EXTENSIONS_SUPPORT 0
#endif
/* AIX requires this to be the first thing in the file. */
#ifndef __GNUC__
# ifndef HAVE_ALLOCA_H
# ifdef _AIX
# pragma alloca
# else
# ifndef alloca /* predefined by HP cc +Olibcalls */
char *alloca();
# endif
# endif
# endif
#endif
/* Compatibility with non-clang compilers */
#ifndef __has_attribute
# define __has_attribute(x) 0
#endif
/* GCC x.y.z supplies __GNUC__ = x and __GNUC_MINOR__ = y */
#ifdef __GNUC__
# define ZEND_GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
#else
# define ZEND_GCC_VERSION 0
#endif
#if ZEND_GCC_VERSION >= 2096
# define ZEND_ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
#else
# define ZEND_ATTRIBUTE_MALLOC
#endif
#if ZEND_GCC_VERSION >= 4003 || __has_attribute(alloc_size)
# define ZEND_ATTRIBUTE_ALLOC_SIZE(X) __attribute__ ((alloc_size(X)))
# define ZEND_ATTRIBUTE_ALLOC_SIZE2(X,Y) __attribute__ ((alloc_size(X,Y)))
#else
# define ZEND_ATTRIBUTE_ALLOC_SIZE(X)
# define ZEND_ATTRIBUTE_ALLOC_SIZE2(X,Y)
#endif
/* Format string checks are disabled by default, because we use custom format modifiers (like %p),
* which cause a large amount of false positives. You can enable format checks by adding
* -DZEND_CHECK_FORMAT_STRINGS to CFLAGS. */
#if defined(ZEND_CHECK_FORMAT_STRINGS) && (ZEND_GCC_VERSION >= 2007 || __has_attribute(format))
# define ZEND_ATTRIBUTE_FORMAT(type, idx, first) __attribute__ ((format(type, idx, first)))
#else
# define ZEND_ATTRIBUTE_FORMAT(type, idx, first)
#endif
#if defined(ZEND_CHECK_FORMAT_STRINGS) && ((ZEND_GCC_VERSION >= 3001 && !defined(__INTEL_COMPILER)) || __has_attribute(format))
# define ZEND_ATTRIBUTE_PTR_FORMAT(type, idx, first) __attribute__ ((format(type, idx, first)))
#else
# define ZEND_ATTRIBUTE_PTR_FORMAT(type, idx, first)
#endif
#if ZEND_GCC_VERSION >= 3001 || __has_attribute(deprecated)
# define ZEND_ATTRIBUTE_DEPRECATED __attribute__((deprecated))
#elif defined(ZEND_WIN32) && defined(_MSC_VER) && _MSC_VER >= 1300
# define ZEND_ATTRIBUTE_DEPRECATED __declspec(deprecated)
#else
# define ZEND_ATTRIBUTE_DEPRECATED
#endif
#if defined(__GNUC__) && ZEND_GCC_VERSION >= 4003
# define ZEND_ATTRIBUTE_UNUSED __attribute__((unused))
# define ZEND_ATTRIBUTE_UNUSED_LABEL __attribute__((cold, unused));
#else
# define ZEND_ATTRIBUTE_UNUSED
# define ZEND_ATTRIBUTE_UNUSED_LABEL
#endif
#if defined(__GNUC__) && ZEND_GCC_VERSION >= 3004 && defined(__i386__)
# define ZEND_FASTCALL __attribute__((fastcall))
#elif defined(_MSC_VER) && defined(_M_IX86)
# define ZEND_FASTCALL __fastcall
#else
# define ZEND_FASTCALL
#endif
#if defined(__GNUC__) && ZEND_GCC_VERSION >= 3004
#else
# define __restrict__
#endif
#define restrict __restrict__
#if (defined(__GNUC__) && __GNUC__ >= 3 && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) && !defined(__osf__)) || __has_attribute(noreturn)
# define HAVE_NORETURN
# define ZEND_NORETURN __attribute__((noreturn))
#elif defined(ZEND_WIN32)
# define HAVE_NORETURN
# define ZEND_NORETURN __declspec(noreturn)
#else
# define ZEND_NORETURN
#endif
#if ZEND_DEBUG
# define zend_always_inline inline
# define zend_never_inline
#else
# if defined(__GNUC__)
# if __GNUC__ >= 3
# define zend_always_inline inline __attribute__((always_inline))
# define zend_never_inline __attribute__((noinline))
# else
# define zend_always_inline inline
# define zend_never_inline
# endif
# elif defined(_MSC_VER)
# define zend_always_inline __forceinline
# define zend_never_inline
# else
# if __has_attribute(always_inline)
# define zend_always_inline inline __attribute__((always_inline))
# else
# define zend_always_inline inline
# endif
# if __has_attribute(noinline)
# define zend_never_inline __attribute__((noinline))
# else
# define zend_never_inline
# endif
# endif
#endif /* ZEND_DEBUG */
#if (defined (__GNUC__) && __GNUC__ > 2 ) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX)
# define EXPECTED(condition) __builtin_expect(!(!(condition)), 1)
# define UNEXPECTED(condition) __builtin_expect(!(!(condition)), 0)
#else
# define EXPECTED(condition) (condition)
# define UNEXPECTED(condition) (condition)
#endif
#ifndef XtOffsetOf
# if defined(CRAY) || (defined(__ARMCC_VERSION) && !defined(LINUX))
# ifdef __STDC__
# define XtOffset(p_type, field) _Offsetof(p_type, field)
# else
# ifdef CRAY2
# define XtOffset(p_type, field) \
(sizeof(int)*((unsigned int)&(((p_type)NULL)->field)))
# else /* !CRAY2 */
# define XtOffset(p_type, field) ((unsigned int)&(((p_type)NULL)->field))
# endif /* !CRAY2 */
# endif /* __STDC__ */
# else /* ! (CRAY || __arm) */
# define XtOffset(p_type, field) \
((zend_long) (((char *) (&(((p_type)NULL)->field))) - ((char *) NULL)))
# endif /* !CRAY */
# ifdef offsetof
# define XtOffsetOf(s_type, field) offsetof(s_type, field)
# else
# define XtOffsetOf(s_type, field) XtOffset(s_type*, field)
# endif
#endif
#if (HAVE_ALLOCA || (defined (__GNUC__) && __GNUC__ >= 2)) && !(defined(ZTS) && defined(NETWARE)) && !(defined(ZTS) && defined(HPUX)) && !defined(DARWIN)
# define ZEND_ALLOCA_MAX_SIZE (32 * 1024)
# define ALLOCA_FLAG(name) \
zend_bool name;
# define SET_ALLOCA_FLAG(name) \
name = 1
# define do_alloca_ex(size, limit, use_heap) \
((use_heap = (UNEXPECTED((size) > (limit)))) ? emalloc(size) : alloca(size))
# define do_alloca(size, use_heap) \
do_alloca_ex(size, ZEND_ALLOCA_MAX_SIZE, use_heap)
# define free_alloca(p, use_heap) \
do { if (UNEXPECTED(use_heap)) efree(p); } while (0)
#else
# define ALLOCA_FLAG(name)
# define SET_ALLOCA_FLAG(name)
# define do_alloca(p, use_heap) emalloc(p)
# define free_alloca(p, use_heap) efree(p)
#endif
#ifdef HAVE_SIGSETJMP
# define SETJMP(a) sigsetjmp(a, 0)
# define LONGJMP(a,b) siglongjmp(a, b)
# define JMP_BUF sigjmp_buf
#else
# define SETJMP(a) setjmp(a)
# define LONGJMP(a,b) longjmp(a, b)
# define JMP_BUF jmp_buf
#endif
#if ZEND_DEBUG
# define ZEND_FILE_LINE_D const char *__zend_filename, const uint __zend_lineno
# define ZEND_FILE_LINE_DC , ZEND_FILE_LINE_D
# define ZEND_FILE_LINE_ORIG_D const char *__zend_orig_filename, const uint __zend_orig_lineno
# define ZEND_FILE_LINE_ORIG_DC , ZEND_FILE_LINE_ORIG_D
# define ZEND_FILE_LINE_RELAY_C __zend_filename, __zend_lineno
# define ZEND_FILE_LINE_RELAY_CC , ZEND_FILE_LINE_RELAY_C
# define ZEND_FILE_LINE_C __FILE__, __LINE__
# define ZEND_FILE_LINE_CC , ZEND_FILE_LINE_C
# define ZEND_FILE_LINE_EMPTY_C NULL, 0
# define ZEND_FILE_LINE_EMPTY_CC , ZEND_FILE_LINE_EMPTY_C
# define ZEND_FILE_LINE_ORIG_RELAY_C __zend_orig_filename, __zend_orig_lineno
# define ZEND_FILE_LINE_ORIG_RELAY_CC , ZEND_FILE_LINE_ORIG_RELAY_C
# define ZEND_ASSERT(c) assert(c)
#else
# define ZEND_FILE_LINE_D
# define ZEND_FILE_LINE_DC
# define ZEND_FILE_LINE_ORIG_D
# define ZEND_FILE_LINE_ORIG_DC
# define ZEND_FILE_LINE_RELAY_C
# define ZEND_FILE_LINE_RELAY_CC
# define ZEND_FILE_LINE_C
# define ZEND_FILE_LINE_CC
# define ZEND_FILE_LINE_EMPTY_C
# define ZEND_FILE_LINE_EMPTY_CC
# define ZEND_FILE_LINE_ORIG_RELAY_C
# define ZEND_FILE_LINE_ORIG_RELAY_CC
# define ZEND_ASSERT(c)
#endif /* ZEND_DEBUG */
#if ZEND_DEBUG
# define Z_DBG(expr) (expr)
#else
# define Z_DBG(expr)
#endif
#ifdef ZTS
# define ZTS_V 1
#else
# define ZTS_V 0
#endif
#ifndef LONG_MAX
# define LONG_MAX 2147483647L
#endif
#ifndef LONG_MIN
# define LONG_MIN (- LONG_MAX - 1)
#endif
#define MAX_LENGTH_OF_DOUBLE 32
#undef MIN
#undef MAX
#define MAX(a, b) (((a)>(b))?(a):(b))
#define MIN(a, b) (((a)<(b))?(a):(b))
#define ZEND_STRL(str) (str), (sizeof(str)-1)
#define ZEND_STRS(str) (str), (sizeof(str))
#define ZEND_NORMALIZE_BOOL(n) \
((n) ? (((n)>0) ? 1 : -1) : 0)
#define ZEND_TRUTH(x) ((x) ? 1 : 0)
#define ZEND_LOG_XOR(a, b) (ZEND_TRUTH(a) ^ ZEND_TRUTH(b))
#define ZEND_MAX_RESERVED_RESOURCES 4
/* excpt.h on Digital Unix 4.0 defines function_table */
#undef function_table
#ifdef ZEND_WIN32
#define ZEND_SECURE_ZERO(var, size) RtlSecureZeroMemory((var), (size))
#else
#define ZEND_SECURE_ZERO(var, size) memset((var), 0, (size))
#endif
#endif /* ZEND_PORTABILITY_H */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* indent-tabs-mode: t
* End:
*/

View File

@@ -111,7 +111,7 @@ static zend_always_inline void *zend_ptr_stack_pop(zend_ptr_stack *stack)
return *(--stack->top_element);
}
static inline void *zend_ptr_stack_top(zend_ptr_stack *stack)
static zend_always_inline void *zend_ptr_stack_top(zend_ptr_stack *stack)
{
return stack->elements[stack->top - 1];
}

View File

@@ -63,14 +63,14 @@ typedef struct _zend_stream {
} zend_stream;
typedef struct _zend_file_handle {
zend_stream_type type;
const char *filename;
char *opened_path;
union {
int fd;
FILE *fp;
zend_stream stream;
} handle;
const char *filename;
char *opened_path;
zend_stream_type type;
zend_bool free_filename;
} zend_file_handle;

View File

@@ -80,7 +80,7 @@ void zend_interned_strings_dtor(TSRMLS_D)
#ifndef ZTS
zend_hash_destroy(&CG(interned_strings));
#else
free(CG(empty_string));
zend_string_release(CG(empty_string));
#endif
}

View File

@@ -140,7 +140,7 @@ static zend_always_inline zend_string *zend_string_init(const char *str, size_t
static zend_always_inline zend_string *zend_string_copy(zend_string *s)
{
if (!IS_INTERNED(s)) {
zend_string_addref(s);
GC_REFCOUNT(s)++;
}
return s;
}
@@ -161,14 +161,14 @@ static zend_always_inline zend_string *zend_string_realloc(zend_string *s, size_
if (IS_INTERNED(s)) {
ret = zend_string_alloc(len, persistent);
memcpy(ret->val, s->val, (len > s->len ? s->len : len) + 1);
} else if (EXPECTED(zend_string_refcount(s) == 1)) {
} else if (EXPECTED(GC_REFCOUNT(s) == 1)) {
ret = (zend_string *)perealloc(s, ZEND_MM_ALIGNED_SIZE(_STR_HEADER_SIZE + len + 1), persistent);
ret->len = len;
zend_string_forget_hash_val(ret);
} else {
ret = zend_string_alloc(len, persistent);
memcpy(ret->val, s->val, (len > s->len ? s->len : len) + 1);
zend_string_delref(s);
GC_REFCOUNT(s)--;
}
return ret;
}
@@ -180,14 +180,14 @@ static zend_always_inline zend_string *zend_string_safe_realloc(zend_string *s,
if (IS_INTERNED(s)) {
ret = zend_string_safe_alloc(n, m, l, persistent);
memcpy(ret->val, s->val, ((n * m) + l > (size_t)s->len ? (size_t)s->len : ((n * m) + l)) + 1);
} else if (zend_string_refcount(s) == 1) {
} else if (GC_REFCOUNT(s) == 1) {
ret = (zend_string *)safe_perealloc(s, n, m, ZEND_MM_ALIGNED_SIZE(_STR_HEADER_SIZE + l + 1), persistent);
ret->len = (n * m) + l;
zend_string_forget_hash_val(ret);
} else {
ret = zend_string_safe_alloc(n, m, l, persistent);
memcpy(ret->val, s->val, ((n * m) + l > (size_t)s->len ? (size_t)s->len : ((n * m) + l)) + 1);
zend_string_delref(s);
GC_REFCOUNT(s)--;
}
return ret;
}
@@ -195,7 +195,7 @@ static zend_always_inline zend_string *zend_string_safe_realloc(zend_string *s,
static zend_always_inline void zend_string_free(zend_string *s)
{
if (!IS_INTERNED(s)) {
ZEND_ASSERT(zend_string_refcount(s) <= 1);
ZEND_ASSERT(GC_REFCOUNT(s) <= 1);
pefree(s, GC_FLAGS(s) & IS_STR_PERSISTENT);
}
}
@@ -203,7 +203,7 @@ static zend_always_inline void zend_string_free(zend_string *s)
static zend_always_inline void zend_string_release(zend_string *s)
{
if (!IS_INTERNED(s)) {
if (zend_string_delref(s) == 0) {
if (--GC_REFCOUNT(s) == 0) {
pefree(s, GC_FLAGS(s) & IS_STR_PERSISTENT);
}
}
@@ -253,7 +253,7 @@ static zend_always_inline zend_bool zend_string_equals(zend_string *s1, zend_str
* -- Ralf S. Engelschall <rse@engelschall.com>
*/
static inline zend_ulong zend_inline_hash_func(const char *str, size_t len)
static zend_always_inline zend_ulong zend_inline_hash_func(const char *str, size_t len)
{
register zend_ulong hash = Z_UL(5381);

View File

@@ -110,12 +110,12 @@ ZEND_API zval *_zend_ts_hash_add_or_update(TsHashTable *ht, zend_string *key, zv
return retval;
}
ZEND_API zval *_zend_ts_hash_index_update_or_next_insert(TsHashTable *ht, zend_ulong h, zval *pData, int flag ZEND_FILE_LINE_DC)
ZEND_API zval *_zend_ts_hash_index_add_or_update(TsHashTable *ht, zend_ulong h, zval *pData, int flag ZEND_FILE_LINE_DC)
{
zval *retval;
begin_write(ht);
retval = _zend_hash_index_update_or_next_insert(TS_HASH(ht), h, pData, flag ZEND_FILE_LINE_RELAY_CC);
retval = _zend_hash_index_add_or_update(TS_HASH(ht), h, pData, flag ZEND_FILE_LINE_RELAY_CC);
end_write(ht);
return retval;

View File

@@ -55,11 +55,11 @@ ZEND_API zval *_zend_ts_hash_add_or_update(TsHashTable *ht, zend_string *key, zv
#define zend_ts_hash_add(ht, key, pData) \
_zend_ts_hash_add_or_update(ht, key, pData, HASH_ADD ZEND_FILE_LINE_CC)
ZEND_API zval *_zend_ts_hash_index_update_or_next_insert(TsHashTable *ht, zend_ulong h, zval *pData, int flag ZEND_FILE_LINE_DC);
ZEND_API zval *_zend_ts_hash_index_add_or_update(TsHashTable *ht, zend_ulong h, zval *pData, int flag ZEND_FILE_LINE_DC);
#define zend_ts_hash_index_update(ht, h, pData) \
_zend_ts_hash_index_update_or_next_insert(ht, h, pData, HASH_UPDATE ZEND_FILE_LINE_CC)
_zend_ts_hash_index_add_or_update(ht, h, pData, HASH_UPDATE ZEND_FILE_LINE_CC)
#define zend_ts_hash_next_index_insert(ht, pData) \
_zend_ts_hash_index_update_or_next_insert(ht, 0, pData, HASH_NEXT_INSERT ZEND_FILE_LINE_CC)
_zend_ts_hash_index_add_or_update(ht, ht->nNextFreeElement, pData, HASH_ADD ZEND_FILE_LINE_CC)
ZEND_API zval* zend_ts_hash_add_empty_element(TsHashTable *ht, zend_string *key);
@@ -111,7 +111,7 @@ ZEND_API zval *_zend_ts_hash_str_add(TsHashTable *ht, const char *key, int len,
#define zend_ts_hash_str_add(ht, key, len, pData) \
_zend_ts_hash_str_add(ht, key, len, pData ZEND_FILE_LINE_CC)
static inline void *zend_ts_hash_str_find_ptr(TsHashTable *ht, const char *str, int len)
static zend_always_inline void *zend_ts_hash_str_find_ptr(TsHashTable *ht, const char *str, int len)
{
zval *zv;
@@ -119,7 +119,7 @@ static inline void *zend_ts_hash_str_find_ptr(TsHashTable *ht, const char *str,
return zv ? Z_PTR_P(zv) : NULL;
}
static inline void *zend_ts_hash_str_update_ptr(TsHashTable *ht, const char *str, int len, void *pData)
static zend_always_inline void *zend_ts_hash_str_update_ptr(TsHashTable *ht, const char *str, int len, void *pData)
{
zval tmp, *zv;
@@ -128,7 +128,7 @@ static inline void *zend_ts_hash_str_update_ptr(TsHashTable *ht, const char *str
return zv ? Z_PTR_P(zv) : NULL;
}
static inline void *zend_ts_hash_str_add_ptr(TsHashTable *ht, const char *str, int len, void *pData)
static zend_always_inline void *zend_ts_hash_str_add_ptr(TsHashTable *ht, const char *str, int len, void *pData)
{
zval tmp, *zv;

View File

@@ -14,6 +14,7 @@
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
| Dmitry Stogov <dmitry@zend.com> |
+----------------------------------------------------------------------+
*/
@@ -22,6 +23,7 @@
#ifndef ZEND_TYPES_H
#define ZEND_TYPES_H
#include "zend_portability.h"
#include "zend_long.h"
#ifdef WORDS_BIGENDIAN
@@ -43,6 +45,11 @@
typedef unsigned char zend_bool;
typedef unsigned char zend_uchar;
typedef enum {
SUCCESS = 0,
FAILURE = -1, /* this MUST stay a negative number, or it may affect functions! */
} ZEND_RESULT_CODE;
#ifdef ZEND_ENABLE_ZVAL_LONG64
# ifdef ZEND_WIN32
# define ZEND_SIZE_MAX _UI64_MAX
@@ -101,7 +108,7 @@ typedef void (*dtor_func_t)(zval *pDest);
typedef void (*copy_ctor_func_t)(zval *pElement);
typedef union _zend_value {
zend_long lval; /* long value */
zend_long lval; /* long value */
double dval; /* double value */
zend_refcounted *counted;
zend_string *str;
@@ -131,9 +138,9 @@ struct _zval_struct {
union {
uint32_t var_flags;
uint32_t next; /* hash collision chain */
uint32_t str_offset; /* string offset */
uint32_t cache_slot; /* literal cache slot */
uint32_t lineno; /* line number (for ast nodes) */
uint32_t silence_num; /* BEGIN_SILENCE op number */
} u2;
};
@@ -144,7 +151,7 @@ struct _zend_refcounted {
ZEND_ENDIAN_LOHI_3(
zend_uchar type,
zend_uchar flags, /* used for strings & objects */
uint16_t gc_info) /* keeps GC root number (or 0) and color */
uint16_t gc_info) /* keeps GC root number (or 0) and color */
} v;
uint32_t type_info;
} u;
@@ -152,33 +159,33 @@ struct _zend_refcounted {
struct _zend_string {
zend_refcounted gc;
zend_ulong h; /* hash value */
size_t len;
zend_ulong h; /* hash value */
size_t len;
char val[1];
};
typedef struct _Bucket {
zend_ulong h; /* hash value (or numeric index) */
zend_ulong h; /* hash value (or numeric index) */
zend_string *key; /* string key or NULL for numerics */
zval val;
} Bucket;
typedef struct _HashTable {
uint32_t nTableSize;
uint32_t nTableMask;
uint32_t nNumUsed;
uint32_t nNumOfElements;
zend_long nNextFreeElement;
uint32_t nTableSize;
uint32_t nTableMask;
uint32_t nNumUsed;
uint32_t nNumOfElements;
zend_long nNextFreeElement;
Bucket *arData;
uint32_t *arHash;
uint32_t *arHash;
dtor_func_t pDestructor;
uint32_t nInternalPointer;
uint32_t nInternalPointer;
union {
struct {
ZEND_ENDIAN_LOHI_3(
zend_uchar flags,
zend_uchar nApplyCount,
uint16_t reserve)
uint16_t reserve)
} v;
uint32_t flags;
} u;
@@ -191,7 +198,7 @@ struct _zend_array {
struct _zend_object {
zend_refcounted gc;
uint32_t handle; // TODO: may be removed ???
uint32_t handle; // TODO: may be removed ???
zend_class_entry *ce;
const zend_object_handlers *handlers;
HashTable *properties;
@@ -201,7 +208,7 @@ struct _zend_object {
struct _zend_resource {
zend_refcounted gc;
zend_long handle; // TODO: may be removed ???
zend_long handle; // TODO: may be removed ???
int type;
void *ptr;
};
@@ -239,10 +246,9 @@ struct _zend_ast_ref {
/* internal types */
#define IS_INDIRECT 15
#define IS_STR_OFFSET 16
#define IS_PTR 17
static inline zend_uchar zval_get_type(const zval* pz) {
static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
return pz->u1.v.type;
}
@@ -520,10 +526,10 @@ static inline zend_uchar zval_get_type(const zval* pz) {
IS_STRING_EX; \
} while (0)
#define ZVAL_INTERNED_STR(z, s) do { \
zval *__z = (z); \
zend_string *__s = (s); \
Z_STR_P(__z) = __s; \
#define ZVAL_INTERNED_STR(z, s) do { \
zval *__z = (z); \
zend_string *__s = (s); \
Z_STR_P(__z) = __s; \
Z_TYPE_INFO_P(__z) = IS_INTERNED_STRING_EX; \
} while (0)
@@ -531,10 +537,22 @@ static inline zend_uchar zval_get_type(const zval* pz) {
zval *__z = (z); \
zend_string *__s = (s); \
Z_STR_P(__z) = __s; \
/* interned strings support */ \
Z_TYPE_INFO_P(__z) = IS_STRING_EX; \
} while (0)
#define ZVAL_STR_COPY(z, s) do { \
zval *__z = (z); \
zend_string *__s = (s); \
Z_STR_P(__z) = __s; \
/* interned strings support */ \
if (IS_INTERNED(__s)) { \
Z_TYPE_INFO_P(__z) = IS_INTERNED_STRING_EX; \
} else { \
GC_REFCOUNT(__s)++; \
Z_TYPE_INFO_P(__z) = IS_STRING_EX; \
} \
} while (0)
#define ZVAL_ARR(z, a) do { \
zval *__z = (z); \
Z_ARR_P(__z) = (a); \
@@ -573,26 +591,26 @@ static inline zend_uchar zval_get_type(const zval* pz) {
#define ZVAL_NEW_RES(z, h, p, t) do { \
zend_resource *_res = emalloc(sizeof(zend_resource)); \
zval *__z; \
zval *__z; \
GC_REFCOUNT(_res) = 1; \
GC_TYPE_INFO(_res) = IS_RESOURCE; \
_res->handle = (h); \
_res->type = (t); \
_res->ptr = (p); \
__z = (z); \
__z = (z); \
Z_RES_P(__z) = _res; \
Z_TYPE_INFO_P(__z) = IS_RESOURCE_EX; \
} while (0)
#define ZVAL_NEW_PERSISTENT_RES(z, h, p, t) do { \
zend_resource *_res = malloc(sizeof(zend_resource)); \
zval *__z; \
zval *__z; \
GC_REFCOUNT(_res) = 1; \
GC_TYPE_INFO(_res) = IS_RESOURCE; \
_res->handle = (h); \
_res->type = (t); \
_res->ptr = (p); \
__z = (z); \
__z = (z); \
Z_RES_P(__z) = _res; \
Z_TYPE_INFO_P(__z) = IS_RESOURCE_EX; \
} while (0)
@@ -651,17 +669,168 @@ static inline zend_uchar zval_get_type(const zval* pz) {
Z_TYPE_INFO_P(z) = IS_PTR; \
} while (0)
#define Z_REFCOUNT_P(pz) zval_refcount_p(pz)
#define Z_SET_REFCOUNT_P(pz, rc) zval_set_refcount_p(pz, rc)
#define Z_ADDREF_P(pz) zval_addref_p(pz)
#define Z_DELREF_P(pz) zval_delref_p(pz)
#define Z_STR_OFFSET_STR(zval) Z_INDIRECT(zval)
#define Z_STR_OFFSET_STR_P(zval_p) Z_STR_OFFSET_STR(*(zval_p))
#define Z_REFCOUNT(z) Z_REFCOUNT_P(&(z))
#define Z_SET_REFCOUNT(z, rc) Z_SET_REFCOUNT_P(&(z), rc)
#define Z_ADDREF(z) Z_ADDREF_P(&(z))
#define Z_DELREF(z) Z_DELREF_P(&(z))
#define Z_STR_OFFSET_IDX(zval) (zval).u2.str_offset
#define Z_STR_OFFSET_IDX_P(zval_p) Z_STR_OFFSET_IDX(*(zval_p))
#define Z_TRY_ADDREF_P(pz) do { \
if (Z_REFCOUNTED_P((pz))) { \
Z_ADDREF_P((pz)); \
} \
} while (0)
#define ZVAL_STR_OFFSET(z, s, i) do { \
Z_STR_OFFSET_STR_P(z) = (s); \
Z_STR_OFFSET_IDX_P(z) = (i); \
Z_TYPE_INFO_P(z) = IS_STR_OFFSET; \
#define Z_TRY_DELREF_P(pz) do { \
if (Z_REFCOUNTED_P((pz))) { \
Z_DELREF_P((pz)); \
} \
} while (0)
#define Z_TRY_ADDREF(z) Z_TRY_ADDREF_P(&(z))
#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));
return GC_REFCOUNT(Z_COUNTED_P(pz));
}
static zend_always_inline uint32_t zval_set_refcount_p(zval* pz, uint32_t rc) {
ZEND_ASSERT(Z_REFCOUNTED_P(pz));
return GC_REFCOUNT(Z_COUNTED_P(pz)) = rc;
}
static zend_always_inline uint32_t zval_addref_p(zval* pz) {
ZEND_ASSERT(Z_REFCOUNTED_P(pz));
return ++GC_REFCOUNT(Z_COUNTED_P(pz));
}
static zend_always_inline uint32_t zval_delref_p(zval* pz) {
ZEND_ASSERT(Z_REFCOUNTED_P(pz));
return --GC_REFCOUNT(Z_COUNTED_P(pz));
}
#define ZVAL_COPY_VALUE(z, v) \
do { \
zval *_z1 = (z); \
zval *_z2 = (v); \
(_z1)->value = (_z2)->value; \
Z_TYPE_INFO_P(_z1) = Z_TYPE_INFO_P(_z2); \
} while (0)
#define ZVAL_COPY(z, v) \
do { \
zval *__z1 = (z); \
zval *__z2 = (v); \
ZVAL_COPY_VALUE(__z1, __z2); \
if (Z_OPT_REFCOUNTED_P(__z1)) { \
Z_ADDREF_P(__z1); \
} \
} while (0)
#define ZVAL_DUP(z, v) \
do { \
zval *__z1 = (z); \
zval *__z2 = (v); \
ZVAL_COPY_VALUE(__z1, __z2); \
zval_opt_copy_ctor(__z1); \
} while (0)
#define ZVAL_DEREF(z) do { \
if (UNEXPECTED(Z_ISREF_P(z))) { \
(z) = Z_REFVAL_P(z); \
} \
} while (0)
#define ZVAL_MAKE_REF(zv) do { \
zval *__zv = (zv); \
if (!Z_ISREF_P(__zv)) { \
ZVAL_NEW_REF(__zv, __zv); \
} \
} while (0)
#define ZVAL_UNREF(z) do { \
zval *_z = (z); \
zend_reference *ref; \
ZEND_ASSERT(Z_ISREF_P(_z)); \
ref = Z_REF_P(_z); \
ZVAL_COPY_VALUE(_z, &ref->val); \
efree_size(ref, sizeof(zend_reference)); \
} while (0)
#define SEPARATE_STRING(zv) do { \
zval *_zv = (zv); \
if (Z_REFCOUNTED_P(_zv) && \
Z_REFCOUNT_P(_zv) > 1) { \
Z_DELREF_P(_zv); \
zval_copy_ctor_func(_zv); \
} \
} while (0)
#define SEPARATE_ARRAY(zv) do { \
zval *_zv = (zv); \
if (Z_REFCOUNT_P(_zv) > 1) { \
if (!Z_IMMUTABLE_P(_zv)) { \
Z_DELREF_P(_zv); \
} \
zval_copy_ctor_func(_zv); \
} \
} while (0)
#define SEPARATE_ZVAL_NOREF(zv) do { \
zval *_zv = (zv); \
if (Z_COPYABLE_P(_zv) || \
Z_IMMUTABLE_P(_zv)) { \
if (Z_REFCOUNT_P(_zv) > 1) { \
if (!Z_IMMUTABLE_P(_zv)) { \
Z_DELREF_P(_zv); \
} \
zval_copy_ctor_func(_zv); \
} \
} \
} while (0)
#define SEPARATE_ZVAL(zv) do { \
zval *_zv = (zv); \
if (Z_REFCOUNTED_P(_zv) || \
Z_IMMUTABLE_P(_zv)) { \
if (Z_REFCOUNT_P(_zv) > 1) { \
if (Z_COPYABLE_P(_zv) || \
Z_IMMUTABLE_P(_zv)) { \
if (!Z_IMMUTABLE_P(_zv)) { \
Z_DELREF_P(_zv); \
} \
zval_copy_ctor_func(_zv); \
} else if (Z_ISREF_P(_zv)) { \
Z_DELREF_P(_zv); \
ZVAL_DUP(_zv, Z_REFVAL_P(_zv)); \
} \
} \
} \
} while (0)
#define SEPARATE_ZVAL_IF_NOT_REF(zv) do { \
zval *_zv = (zv); \
if (Z_COPYABLE_P(_zv) || \
Z_IMMUTABLE_P(_zv)) { \
if (Z_REFCOUNT_P(_zv) > 1) { \
if (!Z_IMMUTABLE_P(_zv)) { \
Z_DELREF_P(_zv); \
} \
zval_copy_ctor_func(_zv); \
} \
} \
} while (0)
#define SEPARATE_ARG_IF_REF(varptr) do { \
ZVAL_DEREF(varptr); \
if (Z_REFCOUNTED_P(varptr)) { \
Z_ADDREF_P(varptr); \
} \
} while (0)
#endif /* ZEND_TYPES_H */

View File

@@ -36,6 +36,13 @@ static zend_always_inline void _zval_dtor(zval *zvalue ZEND_FILE_LINE_DC)
_zval_dtor_func(Z_COUNTED_P(zvalue) ZEND_FILE_LINE_RELAY_CC);
}
static zend_always_inline void _zval_ptr_dtor_nogc(zval *zval_ptr ZEND_FILE_LINE_DC)
{
if (Z_REFCOUNTED_P(zval_ptr) && !Z_DELREF_P(zval_ptr)) {
_zval_dtor_func_for_ptr(Z_COUNTED_P(zval_ptr) ZEND_FILE_LINE_RELAY_CC);
}
}
ZEND_API void _zval_copy_ctor_func(zval *zvalue ZEND_FILE_LINE_DC);
#define zval_copy_ctor_func(zv) _zval_copy_ctor_func(zv ZEND_FILE_LINE_CC)
@@ -98,6 +105,7 @@ ZEND_API void _zval_dtor_wrapper(zval *zvalue);
#define zval_opt_copy_ctor_no_imm(zvalue) _zval_opt_copy_ctor_no_imm((zvalue) ZEND_FILE_LINE_CC)
#define zval_dtor(zvalue) _zval_dtor((zvalue) ZEND_FILE_LINE_CC)
#define zval_ptr_dtor(zval_ptr) _zval_ptr_dtor((zval_ptr) ZEND_FILE_LINE_CC)
#define zval_ptr_dtor_nogc(zval_ptr) _zval_ptr_dtor_nogc((zval_ptr) ZEND_FILE_LINE_CC)
#define zval_internal_dtor(zvalue) _zval_internal_dtor((zvalue) ZEND_FILE_LINE_CC)
#define zval_internal_ptr_dtor(zvalue) _zval_internal_ptr_dtor((zvalue) ZEND_FILE_LINE_CC)
#define zval_dtor_wrapper _zval_dtor_wrapper

View File

@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
| PHP Version 7 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+

View File

@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
| PHP Version 7 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -70,7 +70,7 @@ typedef unsigned short mode_t;
#define IS_UNC_PATH(path, len) \
(len >= 2 && IS_SLASH(path[0]) && IS_SLASH(path[1]))
#define IS_ABSOLUTE_PATH(path, len) \
(len >= 2 && ((isalpha(path[0]) && path[1] == ':') || IS_UNC_PATH(path, len)))
(len >= 2 && ((/* is local */isalpha(path[0]) && path[1] == ':') || /* is UNC */IS_SLASH(path[0]) && IS_SLASH(path[1])))
#elif defined(NETWARE)
#ifdef HAVE_DIRENT_H
@@ -213,18 +213,18 @@ CWD_API char *tsrm_realpath(const char *path, char *real_path TSRMLS_DC);
typedef struct _realpath_cache_bucket {
zend_ulong key;
char *path;
int path_len;
char *realpath;
struct _realpath_cache_bucket *next;
time_t expires;
int path_len;
int realpath_len;
int is_dir;
time_t expires;
#ifdef PHP_WIN32
unsigned char is_rvalid;
unsigned char is_readable;
unsigned char is_wvalid;
unsigned char is_writable;
#endif
struct _realpath_cache_bucket *next;
} realpath_cache_bucket;
typedef struct _virtual_cwd_globals {

View File

@@ -335,7 +335,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR
zval *value;
int have_get_ptr = 0;
if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) {
if (OP1_TYPE == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
@@ -430,7 +430,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_dim_helper, VAR|UNUSED|CV, CONST|TMP|VAR
SAVE_OPLINE();
container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW);
if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
} else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (OP1_TYPE == IS_VAR && !OP1_FREE) {
@@ -445,7 +445,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_dim_helper, VAR|UNUSED|CV, CONST|TMP|VAR
var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
}
if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) {
if (UNEXPECTED(var_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");
}
@@ -497,7 +497,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_helper, VAR|UNUSED|CV, CONST|TMP|VAR|UNU
value = GET_OP2_ZVAL_PTR(BP_VAR_R);
var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW);
if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) {
if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");
}
@@ -692,7 +692,7 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR|
property = GET_OP2_ZVAL_PTR(BP_VAR_R);
retval = EX_VAR(opline->result.var);
if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) {
if (OP1_TYPE == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
@@ -784,7 +784,7 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR
property = GET_OP2_ZVAL_PTR(BP_VAR_R);
retval = EX_VAR(opline->result.var);
if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) {
if (OP1_TYPE == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
@@ -867,6 +867,10 @@ ZEND_VM_HANDLER(34, ZEND_PRE_INC, VAR|CV, ANY)
SAVE_OPLINE();
var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW);
if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
fast_increment_function(var_ptr);
if (RETURN_VALUE_USED(opline)) {
@@ -875,9 +879,6 @@ ZEND_VM_HANDLER(34, ZEND_PRE_INC, VAR|CV, ANY)
ZEND_VM_NEXT_OPCODE();
}
if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) {
if (RETURN_VALUE_USED(opline)) {
ZVAL_NULL(EX_VAR(opline->result.var));
@@ -922,6 +923,10 @@ ZEND_VM_HANDLER(35, ZEND_PRE_DEC, VAR|CV, ANY)
SAVE_OPLINE();
var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW);
if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
fast_decrement_function(var_ptr);
if (RETURN_VALUE_USED(opline)) {
@@ -930,9 +935,6 @@ ZEND_VM_HANDLER(35, ZEND_PRE_DEC, VAR|CV, ANY)
ZEND_VM_NEXT_OPCODE();
}
if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) {
if (RETURN_VALUE_USED(opline)) {
ZVAL_NULL(EX_VAR(opline->result.var));
@@ -977,15 +979,16 @@ ZEND_VM_HANDLER(36, ZEND_POST_INC, VAR|CV, ANY)
SAVE_OPLINE();
var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW);
if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
fast_increment_function(var_ptr);
ZEND_VM_NEXT_OPCODE();
}
if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) {
ZVAL_NULL(EX_VAR(opline->result.var));
FREE_OP1_VAR_PTR();
@@ -1031,15 +1034,16 @@ ZEND_VM_HANDLER(37, ZEND_POST_DEC, VAR|CV, ANY)
SAVE_OPLINE();
var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW);
if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
fast_decrement_function(var_ptr);
ZEND_VM_NEXT_OPCODE();
}
if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) {
ZVAL_NULL(EX_VAR(opline->result.var));
FREE_OP1_VAR_PTR();
@@ -1154,8 +1158,7 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, UNUSED|CONST|
zend_error(E_NOTICE,"Undefined variable: %s", name->val);
/* break missing intentionally */
case BP_VAR_IS:
retval = EX_VAR(opline->result.var);
ZVAL_NULL(retval);
retval = &EG(uninitialized_zval);
break;
case BP_VAR_RW:
zend_error(E_NOTICE,"Undefined variable: %s", name->val);
@@ -1175,8 +1178,7 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, UNUSED|CONST|
zend_error(E_NOTICE,"Undefined variable: %s", name->val);
/* break missing intentionally */
case BP_VAR_IS:
retval = EX_VAR(opline->result.var);
ZVAL_NULL(retval);
retval = &EG(uninitialized_zval);
break;
case BP_VAR_RW:
zend_error(E_NOTICE,"Undefined variable: %s", name->val);
@@ -1279,7 +1281,7 @@ ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
SAVE_OPLINE();
container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
if (EXPECTED(opline->extended_value == 0)) {
@@ -1305,7 +1307,7 @@ ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
SAVE_OPLINE();
container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW);
if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC);
@@ -1377,7 +1379,7 @@ ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET, VAR|CV, CONST|TMP|VAR|CV)
SAVE_OPLINE();
container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_UNSET);
if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC);
@@ -1439,7 +1441,7 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
property = GET_OP2_ZVAL_PTR(BP_VAR_R);
container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W);
if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
@@ -1464,7 +1466,7 @@ ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
property = GET_OP2_ZVAL_PTR(BP_VAR_R);
container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW);
if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
@@ -1526,7 +1528,7 @@ ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|
if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_TMP_VAR) {
zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context");
}
if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
@@ -1552,7 +1554,7 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_UNSET);
property = GET_OP2_ZVAL_PTR(BP_VAR_R);
if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
@@ -1598,7 +1600,7 @@ ZEND_VM_HANDLER(136, ZEND_ASSIGN_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
object = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W);
property_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) {
if (OP1_TYPE == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
@@ -1619,7 +1621,7 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
SAVE_OPLINE();
object_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STR_OFFSET)) {
if (OP1_TYPE == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
@@ -1637,35 +1639,30 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
zval *dim = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R);
zval *variable_ptr;
zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, OP2_TYPE TSRMLS_CC);
variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, OP2_TYPE TSRMLS_CC);
FREE_OP2();
value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
zend_assign_to_string_offset(variable_ptr, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
} else if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (IS_TMP_FREE(free_op_data1)) {
zval_dtor(value);
}
if (RETURN_VALUE_USED(opline)) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
FREE_OP_VAR_PTR(free_op_data2);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
if (UNEXPECTED(variable_ptr != NULL)) {
zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
} else {
if ((opline+1)->op1_type == IS_TMP_VAR) {
value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC);
} else if ((opline+1)->op1_type == IS_CONST) {
value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC);
variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (IS_TMP_FREE(free_op_data1)) {
zval_dtor(value);
}
if (RETURN_VALUE_USED(opline)) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
FREE_OP_VAR_PTR(free_op_data2);
} else {
value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC);
value = zend_assign_to_variable(variable_ptr, value, (opline+1)->op1_type TSRMLS_CC);
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
FREE_OP_VAR_PTR(free_op_data2);
}
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
FREE_OP_VAR_PTR(free_op_data2);
}
FREE_OP_IF_VAR(free_op_data1);
FREE_OP_IF_VAR(free_op_data1);
}
FREE_OP1_VAR_PTR();
/* assign_dim has two opcodes! */
@@ -1682,12 +1679,10 @@ ZEND_VM_HANDLER(38, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV)
zval *variable_ptr;
SAVE_OPLINE();
value = GET_OP2_ZVAL_PTR(BP_VAR_R);
value = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R);
variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
zend_assign_to_string_offset(variable_ptr, value, OP2_TYPE, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
} else if (OP1_TYPE == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (OP1_TYPE == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (IS_OP2_TMP_FREE()) {
zval_dtor(value);
}
@@ -1695,13 +1690,7 @@ ZEND_VM_HANDLER(38, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV)
ZVAL_NULL(EX_VAR(opline->result.var));
}
} else {
if (OP2_TYPE == IS_TMP_VAR) {
value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC);
} else if (OP2_TYPE == IS_CONST) {
value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC);
} else {
value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC);
}
value = zend_assign_to_variable(variable_ptr, value, OP2_TYPE TSRMLS_CC);
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
@@ -1750,8 +1739,8 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV)
UNEXPECTED(!Z_ISREF_P(variable_ptr))) {
zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object");
}
if ((OP2_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) ||
(OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET))) {
if ((OP2_TYPE == IS_VAR && UNEXPECTED(value_ptr == NULL)) ||
(OP1_TYPE == IS_VAR && UNEXPECTED(variable_ptr == NULL))) {
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
}
if ((OP1_TYPE == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) ||
@@ -2880,7 +2869,7 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY)
retval_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_STR_OFFSET)) {
if (OP1_TYPE == IS_VAR && UNEXPECTED(retval_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
}
@@ -3116,7 +3105,7 @@ ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, ANY)
SAVE_OPLINE();
varptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(varptr) == IS_STR_OFFSET)) {
if (OP1_TYPE == IS_VAR && UNEXPECTED(varptr == NULL)) {
zend_error_noreturn(E_ERROR, "Only variables can be passed by reference");
}
@@ -3189,7 +3178,7 @@ ZEND_VM_C_LABEL(send_again):
zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, zend_hash_num_elements(ht) TSRMLS_CC);
if (OP1_TYPE != IS_CONST && OP1_TYPE != IS_TMP_VAR && Z_IMMUTABLE_P(args)) {
int i;
uint32_t i;
int separate = 0;
/* check if any of arguments are going to be passed by reference */
@@ -3894,8 +3883,7 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST)
ZVAL_DUP(EX_VAR(opline->result.var), value);
} else if (Z_STRLEN_P(opline->op2.zv) == sizeof("class")-1 && memcmp(Z_STRVAL_P(opline->op2.zv), "class", sizeof("class") - 1) == 0) {
/* "class" is assigned as a case-sensitive keyword from zend_do_resolve_class_name */
ZVAL_STR(EX_VAR(opline->result.var), ce->name);
zend_string_addref(ce->name);
ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name);
} else {
zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(opline->op2.zv));
}
@@ -3915,7 +3903,7 @@ ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMP|VAR|UNUS
if ((OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) &&
(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
expr_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) {
if (OP1_TYPE == IS_VAR && UNEXPECTED(expr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets");
}
ZVAL_MAKE_REF(expr_ptr);
@@ -4165,9 +4153,9 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMP|VAR|CV, ANY)
zend_file_handle file_handle;
char *resolved_path;
resolved_path = zend_resolve_path(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename) TSRMLS_CC);
resolved_path = zend_resolve_path(Z_STRVAL_P(inc_filename), (int)Z_STRLEN_P(inc_filename) TSRMLS_CC);
if (resolved_path) {
failure_retval = zend_hash_str_exists(&EG(included_files), resolved_path, strlen(resolved_path));
failure_retval = zend_hash_str_exists(&EG(included_files), resolved_path, (int)strlen(resolved_path));
} else {
resolved_path = Z_STRVAL_P(inc_filename);
}
@@ -4180,7 +4168,7 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMP|VAR|CV, ANY)
file_handle.opened_path = estrdup(resolved_path);
}
if (zend_hash_str_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path))) {
if (zend_hash_str_add_empty_element(&EG(included_files), file_handle.opened_path, (int)strlen(file_handle.opened_path))) {
new_op_array = zend_compile_file(&file_handle, (opline->extended_value==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC);
zend_destroy_file_handle(&file_handle TSRMLS_CC);
} else {
@@ -4339,6 +4327,9 @@ ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
SAVE_OPLINE();
container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_UNSET);
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
}
if (OP1_TYPE != IS_UNUSED) {
ZVAL_DEREF(container);
SEPARATE_ZVAL_NOREF(container);
@@ -4417,7 +4408,6 @@ ZEND_VM_C_LABEL(numeric_index_dim):
FREE_OP2();
break;
case IS_STRING:
case IS_STR_OFFSET:
zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
ZEND_VM_CONTINUE(); /* bailed out before */
default:
@@ -4438,7 +4428,7 @@ ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
SAVE_OPLINE();
container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_UNSET);
if (OP1_TYPE == IS_VAR && Z_TYPE_P(container) == IS_STR_OFFSET) {
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
}
offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
@@ -4475,17 +4465,15 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
ZVAL_DEREF(array_ptr);
if (Z_TYPE_P(array_ptr) == IS_ARRAY) {
if (!Z_ISREF_P(array_ref)) {
SEPARATE_ZVAL_NOREF(array_ptr);
SEPARATE_ARRAY(array_ptr);
array_ref = array_ptr;
if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
ZVAL_NEW_REF(array_ptr, array_ptr);
array_ref = array_ptr;
array_ptr = Z_REFVAL_P(array_ptr);
}
} else if (Z_IMMUTABLE_P(array_ptr)) {
} else if (Z_IMMUTABLE_P(array_ptr) || Z_REFCOUNT_P(array_ptr) > 1) {
zval_copy_ctor(array_ptr);
} else {
SEPARATE_ZVAL_NOREF(array_ptr);
}
if (Z_REFCOUNTED_P(array_ref)) Z_ADDREF_P(array_ref);
} else if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
@@ -4496,9 +4484,6 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
ce = Z_OBJCE_P(array_ptr);
if (!ce || ce->get_iterator == NULL) {
if (!Z_ISREF_P(array_ref)) {
SEPARATE_ZVAL_NOREF(array_ptr);
}
Z_ADDREF_P(array_ptr);
}
array_ref = array_ptr;
@@ -4611,25 +4596,37 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
}
iter->index = -1; /* will be set to 0 before using next handler */
} else if ((fe_ht = HASH_OF(array_ptr)) != NULL) {
zend_hash_internal_pointer_reset(fe_ht);
if (ce) {
zend_object *zobj = Z_OBJ_P(array_ptr);
while (zend_hash_has_more_elements(fe_ht) == SUCCESS) {
zend_string *str_key;
zend_ulong int_key;
zend_uchar key_type;
HashPointer *ptr = (HashPointer*)EX_VAR((opline+2)->op1.var);
HashPosition pos = 0;
Bucket *p;
key_type = zend_hash_get_current_key(fe_ht, &str_key, &int_key, 0);
if (key_type != HASH_KEY_NON_EXISTENT &&
(key_type == HASH_KEY_IS_LONG ||
zend_check_property_access(zobj, str_key TSRMLS_CC) == SUCCESS)) {
break;
while (1) {
if (pos >= fe_ht->nNumUsed) {
is_empty = 1;
if (OP1_TYPE == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) {
FREE_OP1_VAR_PTR();
}
zend_hash_move_forward(fe_ht);
ZEND_VM_JMP(opline->op2.jmp_addr);
}
p = fe_ht->arData + pos;
if (Z_TYPE(p->val) == IS_UNDEF ||
(Z_TYPE(p->val) == IS_INDIRECT &&
Z_TYPE_P(Z_INDIRECT(p->val)) == IS_UNDEF)) {
pos++;
continue;
}
if (!ce ||
!p->key ||
zend_check_property_access(Z_OBJ_P(array_ptr), p->key TSRMLS_CC) == SUCCESS) {
break;
}
pos++;
}
is_empty = zend_hash_has_more_elements(fe_ht) != SUCCESS;
zend_hash_get_pointer(fe_ht, (HashPointer*)EX_VAR((opline+2)->op1.var));
fe_ht->nInternalPointer = pos;
ptr->pos = pos;
ptr->ht = fe_ht;
ptr->h = fe_ht->arData[pos].h;
is_empty = 0;
} else {
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
is_empty = 1;
@@ -4653,8 +4650,9 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
zval *array, *array_ref;
zval *value;
HashTable *fe_ht;
zend_object_iterator *iter = NULL;
zval *key = NULL;
HashPointer *ptr;
HashPosition pos;
Bucket *p;
array = array_ref = EX_VAR(opline->op1.var);
if (Z_ISREF_P(array)) {
@@ -4664,81 +4662,174 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
zval_copy_ctor(array);
}
}
if (opline->extended_value & ZEND_FE_FETCH_WITH_KEY) {
key = EX_VAR((opline+1)->result.var);
}
SAVE_OPLINE();
switch (zend_iterator_unwrap(array, &iter TSRMLS_CC)) {
default:
case ZEND_ITER_INVALID:
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
if (EXPECTED(Z_TYPE_P(array) == IS_ARRAY)) {
fe_ht = Z_ARRVAL_P(array);
ptr = (HashPointer*)EX_VAR((opline+1)->op1.var);
pos = ptr->pos;
if (UNEXPECTED(pos == INVALID_IDX)) {
/* reached end of iteration */
ZEND_VM_JMP(opline->op2.jmp_addr);
case ZEND_ITER_PLAIN_OBJECT: {
zend_object *zobj = Z_OBJ_P(array);
int key_type;
zend_string *str_key;
zend_ulong int_key;
fe_ht = Z_OBJPROP_P(array);
zend_hash_set_pointer(fe_ht, (HashPointer*)EX_VAR((opline+1)->op1.var));
} else if (UNEXPECTED(ptr->ht != fe_ht)) {
ptr->ht = fe_ht;
pos = 0;
} else if (UNEXPECTED(fe_ht->nInternalPointer != ptr->pos)) {
if (fe_ht->u.flags & HASH_FLAG_PACKED) {
pos = ptr->h;
} else {
pos = fe_ht->arHash[ptr->h & fe_ht->nTableMask];
while (pos != INVALID_IDX) {
if (fe_ht->arData[pos].h == ptr->h && pos == ptr->pos) {
break;
}
pos = Z_NEXT(fe_ht->arData[pos].val);
}
}
}
while (1) {
if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
/* reached end of iteration */
ZEND_VM_JMP(opline->op2.jmp_addr);
}
p = fe_ht->arData + pos;
value = &p->val;
if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
pos++;
continue;
} else if (UNEXPECTED(Z_TYPE_P(value) == IS_INDIRECT)) {
value = Z_INDIRECT_P(value);
if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
pos++;
continue;
}
}
if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
ZVAL_MAKE_REF(value);
Z_ADDREF_P(value);
ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(value));
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
if (opline->extended_value & ZEND_FE_FETCH_WITH_KEY) {
if (!p->key) {
ZVAL_LONG(EX_VAR((opline+1)->result.var), p->h);
} else {
ZVAL_STR_COPY(EX_VAR((opline+1)->result.var), p->key);
}
}
break;
}
do {
pos++;
if (pos >= fe_ht->nNumUsed) {
fe_ht->nInternalPointer = ptr->pos = INVALID_IDX;
ZEND_VM_INC_OPCODE();
ZEND_VM_NEXT_OPCODE();
}
p = fe_ht->arData + pos;
} while (Z_TYPE(p->val) == IS_UNDEF ||
(Z_TYPE(p->val) == IS_INDIRECT &&
Z_TYPE_P(Z_INDIRECT(p->val)) == IS_UNDEF));
fe_ht->nInternalPointer = ptr->pos = pos;
ptr->h = fe_ht->arData[pos].h;
ZEND_VM_INC_OPCODE();
ZEND_VM_NEXT_OPCODE();
} else if (EXPECTED(Z_TYPE_P(array) == IS_OBJECT)) {
zend_object_iterator *iter;
if ((iter = zend_iterator_unwrap(array TSRMLS_CC)) == NULL) {
/* plain object */
zend_object *zobj = Z_OBJ_P(array);
fe_ht = Z_OBJPROP_P(array);
ptr = (HashPointer*)EX_VAR((opline+1)->op1.var);
pos = ptr->pos;
if (pos == INVALID_IDX) {
/* reached end of iteration */
ZEND_VM_JMP(opline->op2.jmp_addr);
} else if (UNEXPECTED(ptr->ht != fe_ht)) {
ptr->ht = fe_ht;
pos = 0;
} else if (UNEXPECTED(fe_ht->nInternalPointer != ptr->pos)) {
if (fe_ht->u.flags & HASH_FLAG_PACKED) {
pos = ptr->h;
} else {
pos = fe_ht->arHash[ptr->h & fe_ht->nTableMask];
while (pos != INVALID_IDX) {
if (fe_ht->arData[pos].h == ptr->h && pos == ptr->pos) {
break;
}
pos = Z_NEXT(fe_ht->arData[pos].val);
}
}
}
while (1) {
if ((value = zend_hash_get_current_data(fe_ht)) == NULL) {
if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
/* reached end of iteration */
ZEND_VM_JMP(opline->op2.jmp_addr);
}
if (Z_TYPE_P(value) == IS_INDIRECT) {
p = fe_ht->arData + pos;
value = &p->val;
if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
pos++;
continue;
} else if (UNEXPECTED(Z_TYPE_P(value) == IS_INDIRECT)) {
value = Z_INDIRECT_P(value);
if (Z_TYPE_P(value) == IS_UNDEF) {
zend_hash_move_forward(fe_ht);
if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
pos++;
continue;
}
}
key_type = zend_hash_get_current_key(fe_ht, &str_key, &int_key, 0);
zend_hash_move_forward(fe_ht);
if (key_type == HASH_KEY_IS_LONG ||
zend_check_property_access(zobj, str_key TSRMLS_CC) == SUCCESS) {
if (UNEXPECTED(!p->key)) {
if (opline->extended_value & ZEND_FE_FETCH_WITH_KEY) {
ZVAL_LONG(EX_VAR((opline+1)->result.var), p->h);
}
break;
} else if (zend_check_property_access(zobj, p->key TSRMLS_CC) == SUCCESS) {
if (opline->extended_value & ZEND_FE_FETCH_WITH_KEY) {
if (p->key->val[0]) {
ZVAL_STR_COPY(EX_VAR((opline+1)->result.var), p->key);
} else {
const char *class_name, *prop_name;
size_t prop_name_len;
zend_unmangle_property_name_ex(
p->key, &class_name, &prop_name, &prop_name_len);
ZVAL_STRINGL(EX_VAR((opline+1)->result.var), prop_name, prop_name_len);
}
}
break;
}
pos++;
}
if (key) {
if (key_type == HASH_KEY_IS_LONG) {
ZVAL_LONG(key, int_key);
} else {
const char *class_name, *prop_name;
int prop_name_len;
zend_unmangle_property_name_ex(
str_key->val, str_key->len, &class_name, &prop_name, &prop_name_len
);
ZVAL_STRINGL(key, prop_name, prop_name_len);
if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
ZVAL_MAKE_REF(value);
Z_ADDREF_P(value);
ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(value));
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
do {
pos++;
if (pos >= fe_ht->nNumUsed) {
fe_ht->nInternalPointer = ptr->pos = INVALID_IDX;
ZEND_VM_INC_OPCODE();
ZEND_VM_NEXT_OPCODE();
}
}
zend_hash_get_pointer(fe_ht, (HashPointer*)EX_VAR((opline+1)->op1.var));
break;
}
case ZEND_ITER_PLAIN_ARRAY:
fe_ht = Z_ARRVAL_P(array);
zend_hash_set_pointer(fe_ht, (HashPointer*)EX_VAR((opline+1)->op1.var));
if ((value = zend_hash_get_current_data(fe_ht)) == NULL) {
/* reached end of iteration */
ZEND_VM_JMP(opline->op2.jmp_addr);
}
if (key) {
zend_hash_get_current_key_zval(fe_ht, key);
}
zend_hash_move_forward(fe_ht);
zend_hash_get_pointer(fe_ht, (HashPointer*)EX_VAR((opline+1)->op1.var));
break;
case ZEND_ITER_OBJECT:
p = fe_ht->arData + pos;
} while (Z_TYPE(p->val) == IS_UNDEF ||
(Z_TYPE(p->val) == IS_INDIRECT &&
Z_TYPE_P(Z_INDIRECT(p->val)) == IS_UNDEF) ||
(EXPECTED(p->key != NULL) &&
zend_check_property_access(zobj, p->key TSRMLS_CC) == FAILURE));
fe_ht->nInternalPointer = ptr->pos = pos;
ptr->h = fe_ht->arData[pos].h;
ZEND_VM_INC_OPCODE();
ZEND_VM_NEXT_OPCODE();
} else {
/* !iter happens from exception */
if (iter && ++iter->index > 0) {
/* This could cause an endless loop if index becomes zero again.
@@ -4767,31 +4858,31 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
/* failure in get_current_data */
ZEND_VM_JMP(opline->op2.jmp_addr);
}
if (key) {
if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
ZVAL_MAKE_REF(value);
Z_ADDREF_P(value);
ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(value));
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
if (opline->extended_value & ZEND_FE_FETCH_WITH_KEY) {
if (iter->funcs->get_current_key) {
iter->funcs->get_current_key(iter, key TSRMLS_CC);
iter->funcs->get_current_key(iter, EX_VAR((opline+1)->result.var) TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
zval_ptr_dtor(array_ref);
HANDLE_EXCEPTION();
}
} else {
ZVAL_LONG(key, iter->index);
ZVAL_LONG(EX_VAR((opline+1)->result.var), iter->index);
}
}
break;
}
if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
ZVAL_MAKE_REF(value);
Z_ADDREF_P(value);
ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(value));
ZEND_VM_INC_OPCODE();
ZEND_VM_NEXT_OPCODE();
}
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
ZEND_VM_JMP(opline->op2.jmp_addr);
}
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
@@ -4967,7 +5058,7 @@ ZEND_VM_C_LABEL(num_index_prop):
}
}
if (Z_TYPE_P(offset) == IS_LONG) {
if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) {
if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) {
if ((opline->extended_value & ZEND_ISSET) ||
Z_STRVAL_P(container)[offset->value.lval] != '0') {
result = 1;
@@ -5051,6 +5142,7 @@ ZEND_VM_HANDLER(57, ZEND_BEGIN_SILENCE, ANY, ANY)
ZVAL_LONG(EX_VAR(opline->result.var), EG(error_reporting));
if (Z_TYPE(EX(old_error_reporting)) == IS_UNDEF) {
ZVAL_LONG(&EX(old_error_reporting), EG(error_reporting));
EX(old_error_reporting).u2.silence_num = opline->op2.num;
}
if (EG(error_reporting)) {
@@ -5071,15 +5163,10 @@ ZEND_VM_HANDLER(57, ZEND_BEGIN_SILENCE, ANY, ANY)
}
if (EXPECTED(zend_hash_str_add_ptr(EG(modified_ini_directives), "error_reporting", sizeof("error_reporting")-1, EG(error_reporting_ini_entry)) != NULL)) {
EG(error_reporting_ini_entry)->orig_value = EG(error_reporting_ini_entry)->value;
EG(error_reporting_ini_entry)->orig_value_length = EG(error_reporting_ini_entry)->value_length;
EG(error_reporting_ini_entry)->orig_modifiable = EG(error_reporting_ini_entry)->modifiable;
EG(error_reporting_ini_entry)->modified = 1;
}
} else if (EG(error_reporting_ini_entry)->value != EG(error_reporting_ini_entry)->orig_value) {
efree(EG(error_reporting_ini_entry)->value);
}
EG(error_reporting_ini_entry)->value = estrndup("0", sizeof("0")-1);
EG(error_reporting_ini_entry)->value_length = sizeof("0")-1;
} while (0);
}
CHECK_EXCEPTION();
@@ -5096,26 +5183,15 @@ ZEND_VM_HANDLER(142, ZEND_RAISE_ABSTRACT_ERROR, ANY, ANY)
ZEND_VM_HANDLER(58, ZEND_END_SILENCE, TMP, ANY)
{
USE_OPLINE
char buf[MAX_LENGTH_OF_LONG + 1];
char *res;
SAVE_OPLINE();
if (!EG(error_reporting) && Z_LVAL_P(EX_VAR(opline->op1.var)) != 0) {
EG(error_reporting) = Z_LVAL_P(EX_VAR(opline->op1.var));
_zend_print_signed_to_buf(buf + sizeof(buf) - 1, EG(error_reporting), zend_ulong, res);
if (EXPECTED(EG(error_reporting_ini_entry) != NULL)) {
if (EXPECTED(EG(error_reporting_ini_entry)->modified &&
EG(error_reporting_ini_entry)->value != EG(error_reporting_ini_entry)->orig_value)) {
efree(EG(error_reporting_ini_entry)->value);
}
EG(error_reporting_ini_entry)->value_length = buf + sizeof(buf) - 1 - res;
EG(error_reporting_ini_entry)->value = estrndup(res, EG(error_reporting_ini_entry)->value_length);
}
}
//??? if (EX(old_error_reporting) == EX_VAR(opline->op1.var)) {
//??? EX(old_error_reporting) = NULL;
//??? }
CHECK_EXCEPTION();
if (Z_TYPE(EX(old_error_reporting)) != IS_UNDEF &&
EX(old_error_reporting).u2.silence_num == opline->op2.num) {
ZVAL_UNDEF(&EX(old_error_reporting));
}
ZEND_VM_NEXT_OPCODE();
}
@@ -5124,36 +5200,15 @@ ZEND_VM_HANDLER(152, ZEND_JMP_SET, CONST|TMP|VAR|CV, ANY)
USE_OPLINE
zend_free_op free_op1;
zval *value;
int is_ref = 0;
SAVE_OPLINE();
value = GET_OP1_ZVAL_PTR(BP_VAR_R);
if (i_zend_is_true(value TSRMLS_CC)) {
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value);
if (OP1_TYPE == IS_CONST) {
if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) {
zval_copy_ctor_func(EX_VAR(opline->result.var));
}
} else if (OP1_TYPE == IS_CV) {
if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
ZEND_VM_JMP(opline->op2.jmp_addr);
if ((OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) && Z_ISREF_P(value)) {
is_ref = 1;
value = Z_REFVAL_P(value);
}
FREE_OP1();
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(158, ZEND_JMP_SET_VAR, CONST|TMP|VAR|CV, ANY)
{
USE_OPLINE
zend_free_op free_op1;
zval *value;
SAVE_OPLINE();
value = GET_OP1_ZVAL_PTR(BP_VAR_R);
if (i_zend_is_true(value TSRMLS_CC)) {
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value);
if (OP1_TYPE == IS_CONST) {
@@ -5162,6 +5217,9 @@ ZEND_VM_HANDLER(158, ZEND_JMP_SET_VAR, CONST|TMP|VAR|CV, ANY)
}
} else if (OP1_TYPE == IS_CV) {
if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
} else if (OP1_TYPE == IS_VAR && is_ref) {
if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
FREE_OP1();
}
ZEND_VM_JMP(opline->op2.jmp_addr);
}
@@ -5180,33 +5238,18 @@ ZEND_VM_HANDLER(22, ZEND_QM_ASSIGN, CONST|TMP|VAR|CV, ANY)
SAVE_OPLINE();
value = GET_OP1_ZVAL_PTR(BP_VAR_R);
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value);
if (OP1_TYPE == IS_CONST) {
if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) {
zval_copy_ctor_func(EX_VAR(opline->result.var));
if ((OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) && Z_ISREF_P(value)) {
ZVAL_COPY(EX_VAR(opline->result.var), Z_REFVAL_P(value));
FREE_OP1();
} else {
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value);
if (OP1_TYPE == IS_CONST) {
if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) {
zval_copy_ctor_func(EX_VAR(opline->result.var));
}
} else if (OP1_TYPE == IS_CV) {
if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
} else if (OP1_TYPE == IS_CV) {
if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(157, ZEND_QM_ASSIGN_VAR, CONST|TMP|VAR|CV, ANY)
{
USE_OPLINE
zend_free_op free_op1;
zval *value;
SAVE_OPLINE();
value = GET_OP1_ZVAL_PTR(BP_VAR_R);
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value);
if (OP1_TYPE == IS_CONST) {
if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) {
zval_copy_ctor_func(EX_VAR(opline->result.var));
}
} else if (OP1_TYPE == IS_CV) {
if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
ZEND_VM_NEXT_OPCODE();
}
@@ -5472,15 +5515,7 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
/* restore previous error_reporting value */
if (!EG(error_reporting) && Z_TYPE(EX(old_error_reporting)) != IS_UNDEF && Z_LVAL(EX(old_error_reporting)) != 0) {
zval restored_error_reporting;
zend_string *key;
ZVAL_LONG(&restored_error_reporting, Z_LVAL(EX(old_error_reporting)));
convert_to_string(&restored_error_reporting);
key = zend_string_init("error_reporting", sizeof("error_reporting")-1, 0);
zend_alter_ini_entry_ex(key, Z_STRVAL(restored_error_reporting), Z_STRLEN(restored_error_reporting), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME, 1 TSRMLS_CC);
zend_string_free(key);
zval_dtor(&restored_error_reporting);
EG(error_reporting) = Z_LVAL(EX(old_error_reporting));
}
ZVAL_UNDEF(&EX(old_error_reporting));
@@ -5672,7 +5707,7 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE
} else {
zval *value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) {
if (OP1_TYPE == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
}
@@ -5847,19 +5882,46 @@ ZEND_VM_HANDLER(168, ZEND_BIND_GLOBAL, CV, CONST)
zval *varname;
zval *value;
zval *variable_ptr;
zend_string *name;
Bucket *p;
uint32_t idx;
SAVE_OPLINE();
varname = GET_OP2_ZVAL_PTR(BP_VAR_R);
name = Z_STR_P(varname);
value = zend_hash_find(&EG(symbol_table).ht, name);
if (value == NULL) {
value = zend_hash_add_new(&EG(symbol_table).ht, name, &EG(uninitialized_zval));
idx = (uint32_t)(uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(varname));
/* index 0 can't be cached (NULL is a mark of uninitialized cache slot) */
p = EG(symbol_table).ht.arData + idx;
if (EXPECTED(idx > 0) &&
EXPECTED(idx < EG(symbol_table).ht.nNumUsed) &&
EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
(EXPECTED(p->key == Z_STR_P(varname)) ||
(EXPECTED(p->h == Z_STR_P(varname)->h) &&
EXPECTED(p->key != NULL) &&
EXPECTED(p->key->len == Z_STRLEN_P(varname)) &&
EXPECTED(memcmp(p->key->val, Z_STRVAL_P(varname), Z_STRLEN_P(varname)) == 0)))) {
value = &EG(symbol_table).ht.arData[idx].val;
/* GLOBAL variable may be an INDIRECT pointer to CV */
} else if (Z_TYPE_P(value) == IS_INDIRECT) {
value = Z_INDIRECT_P(value);
if (Z_TYPE_P(value) == IS_UNDEF) {
ZVAL_NULL(value);
if (UNEXPECTED(Z_TYPE_P(value) == IS_INDIRECT)) {
value = Z_INDIRECT_P(value);
if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
ZVAL_NULL(value);
}
}
} else {
value = zend_hash_find(&EG(symbol_table).ht, Z_STR_P(varname));
if (UNEXPECTED(value == NULL)) {
value = zend_hash_add_new(&EG(symbol_table).ht, Z_STR_P(varname), &EG(uninitialized_zval));
idx = ((char*)value - (char*)EG(symbol_table).ht.arData) / sizeof(Bucket);
CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)idx);
} else {
idx = ((char*)value - (char*)EG(symbol_table).ht.arData) / sizeof(Bucket);
CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)idx);
/* GLOBAL variable may be an INDIRECT pointer to CV */
if (UNEXPECTED(Z_TYPE_P(value) == IS_INDIRECT)) {
value = Z_INDIRECT_P(value);
if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
ZVAL_NULL(value);
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -179,8 +179,8 @@ const char *zend_vm_opcodes_map[169] = {
"ZEND_ADD_TRAIT",
"ZEND_BIND_TRAITS",
"ZEND_SEPARATE",
"ZEND_QM_ASSIGN_VAR",
"ZEND_JMP_SET_VAR",
NULL,
NULL,
"ZEND_DISCARD_EXCEPTION",
"ZEND_YIELD",
"ZEND_GENERATOR_RETURN",

View File

@@ -170,8 +170,6 @@ ZEND_API const char *zend_get_opcode_name(zend_uchar opcode);
#define ZEND_ADD_TRAIT 154
#define ZEND_BIND_TRAITS 155
#define ZEND_SEPARATE 156
#define ZEND_QM_ASSIGN_VAR 157
#define ZEND_JMP_SET_VAR 158
#define ZEND_DISCARD_EXCEPTION 159
#define ZEND_YIELD 160
#define ZEND_GENERATOR_RETURN 161

View File

@@ -1,5 +1,5 @@
# +----------------------------------------------------------------------+
# | PHP Version 5 |
# | PHP Version 7 |
# +----------------------------------------------------------------------+
# | Copyright (c) 1997-2014 The PHP Group |
# +----------------------------------------------------------------------+

View File

@@ -1,5 +1,5 @@
# +----------------------------------------------------------------------+
# | PHP Version 5 |
# | PHP Version 7 |
# +----------------------------------------------------------------------+
# | Copyright (c) 1997-2007 The PHP Group |
# +----------------------------------------------------------------------+

View File

@@ -1,6 +1,6 @@
#! /bin/sh
# +----------------------------------------------------------------------+
# | PHP Version 5 |
# | PHP Version 7 |
# +----------------------------------------------------------------------+
# | Copyright (c) 1997-2007 The PHP Group |
# +----------------------------------------------------------------------+

View File

@@ -1,5 +1,5 @@
# +----------------------------------------------------------------------+
# | PHP Version 5 |
# | PHP Version 7 |
# +----------------------------------------------------------------------+
# | Copyright (c) 2000-2006 The PHP Group |
# +----------------------------------------------------------------------+

View File

@@ -95,10 +95,10 @@ int zend_sprintf(char *buffer, const char *format, ...);
#define zend_isinf(a) 0
#endif
#ifdef HAVE_FINITE
#define zend_finite(a) finite(a)
#elif defined(HAVE_ISFINITE) || defined(isfinite)
#if defined(HAVE_ISFINITE) || defined(isfinite)
#define zend_finite(a) isfinite(a)
#elif defined(HAVE_FINITE)
#define zend_finite(a) finite(a)
#elif defined(fpclassify)
#define zend_finite(a) ((fpclassify((a))!=FP_INFINITE&&fpclassify((a))!=FP_NAN)?1:0)
#else
@@ -787,7 +787,12 @@ if test "$PHP_GCOV" = "yes"; then
AC_MSG_ERROR([ccache must be disabled when --enable-gcov option is used. You can disable ccache by setting environment variable CCACHE_DISABLE=1.])
fi
ltp_version_list="1.5 1.6 1.7 1.9 1.10"
dnl min: 1.5 (i.e. 105, major * 100 + minor for easier comparison)
ltp_version_min="105"
dnl non-working versions, e.g. "1.8 1.18";
dnl remove "none" when introducing the first incompatible LTP version an
dnl separate any following additions by spaces
ltp_version_exclude="1.8"
AC_CHECK_PROG(LTP, lcov, lcov)
AC_CHECK_PROG(LTP_GENHTML, genhtml, genhtml)
@@ -797,21 +802,30 @@ if test "$PHP_GCOV" = "yes"; then
if test "$LTP"; then
AC_CACHE_CHECK([for ltp version], php_cv_ltp_version, [
php_cv_ltp_version=invalid
ltp_version=`$LTP -v 2>/dev/null | $SED -e 's/^.* //'`
for ltp_check_version in $ltp_version_list; do
if test "$ltp_version" = "$ltp_check_version"; then
php_cv_ltp_version="$ltp_check_version (ok)"
ltp_version_vars=`$LTP -v 2>/dev/null | $SED -e 's/^.* //' -e 's/\./ /g' | tr -d a-z`
if test -n "$ltp_version_vars"; then
set $ltp_version_vars
ltp_version="${1}.${2}"
ltp_version_num="`expr ${1} \* 100 + ${2}`"
if test $ltp_version_num -ge $ltp_version_min; then
php_cv_ltp_version="$ltp_version (ok)"
for ltp_check_version in $ltp_version_exclude; do
if test "$ltp_version" = "$ltp_check_version"; then
php_cv_ltp_version=invalid
break
fi
done
fi
done
fi
])
else
ltp_msg="To enable code coverage reporting you must have one of the following LTP versions installed: $ltp_version_list"
ltp_msg="To enable code coverage reporting you must have LTP installed"
AC_MSG_ERROR([$ltp_msg])
fi
case $php_cv_ltp_version in
""|invalid[)]
ltp_msg="You must have one of the following versions of LTP: $ltp_version_list (found: $ltp_version)."
ltp_msg="This LTP version is not supported (found: $ltp_version, min: $ltp_version_min, excluded: $ltp_version_exclude)."
AC_MSG_ERROR([$ltp_msg])
LTP="exit 0;"
;;
@@ -1476,11 +1490,8 @@ PHP_ADD_SOURCES(Zend, \
zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \
zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_gc.c \
zend_closures.c zend_float.c zend_string.c zend_signal.c zend_generators.c \
zend_virtual_cwd.c zend_ast.c)
if test -r "$abs_srcdir/Zend/zend_objects.c"; then
PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_default_classes.c)
fi
zend_virtual_cwd.c zend_ast.c zend_objects.c zend_object_handlers.c zend_objects_API.c \
zend_default_classes.c zend_inheritance.c)
dnl Selectively disable optimization due to high RAM usage during
dnl compiling the executor.

View File

@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
| PHP Version 7 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+

View File

@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
| PHP Version 7 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+

View File

@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
| PHP Version 7 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -359,12 +359,6 @@ static PHP_FUNCTION(bzread)
}
data = zend_string_alloc(len, 0);
data->len = php_stream_read(stream, data->val, data->len);
if (data->len < 0) {
zend_string_free(data);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "could not read valid bz2 data from stream");
RETURN_FALSE;
}
data->val[data->len] = '\0';
RETURN_STR(data);

View File

@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
| PHP Version 7 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -34,17 +34,17 @@ enum strm_status {
};
typedef struct _php_bz2_filter_data {
int persistent;
bz_stream strm;
char *inbuf;
size_t inbuf_len;
char *outbuf;
size_t inbuf_len;
size_t outbuf_len;
/* Decompress options */
enum strm_status status;
unsigned int small_footprint : 1;
unsigned int expect_concatenated : 1;
enum strm_status status; /* Decompress option */
unsigned int small_footprint : 1; /* Decompress option */
unsigned int expect_concatenated : 1; /* Decompress option */
int persistent;
} php_bz2_filter_data;
/* }}} */

View File

@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
| PHP Version 7 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+

View File

@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
| PHP Version 7 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+

View File

@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
| PHP Version 7 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+

View File

@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
| PHP Version 7 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+

View File

@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
| PHP Version 7 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+

View File

@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
| PHP Version 7 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+

View File

@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
| PHP Version 7 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -272,7 +272,7 @@ static PHP_INI_MH(OnTypeLibFileUpdate)
char *strtok_buf = NULL;
int cached;
if (!new_value || !new_value[0] || (typelib_file = VCWD_FOPEN(new_value, "r"))==NULL) {
if (NULL == new_value || !new_value->val[0] || (typelib_file = VCWD_FOPEN(new_value->val, "r"))==NULL) {
return FAILURE;
}

View File

@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
| PHP Version 7 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+

View File

@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
| PHP Version 7 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+

View File

@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
| PHP Version 7 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+

View File

@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
| PHP Version 7 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+

View File

@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
| PHP Version 7 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+

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