1999-04-08 02:10:10 +08:00
|
|
|
/*
|
|
|
|
+----------------------------------------------------------------------+
|
|
|
|
| Zend Engine |
|
|
|
|
+----------------------------------------------------------------------+
|
2015-01-15 23:27:30 +08:00
|
|
|
| Copyright (c) 1998-2015 Zend Technologies Ltd. (http://www.zend.com) |
|
1999-04-08 02:10:10 +08:00
|
|
|
+----------------------------------------------------------------------+
|
2001-12-11 23:16:21 +08:00
|
|
|
| This source file is subject to version 2.00 of the Zend license, |
|
1999-07-16 22:58:16 +08:00
|
|
|
| that is bundled with this package in the file LICENSE, and is |
|
2003-06-11 04:04:29 +08:00
|
|
|
| available through the world-wide-web at the following url: |
|
2001-12-11 23:16:21 +08:00
|
|
|
| http://www.zend.com/license/2_00.txt. |
|
1999-07-16 22:58:16 +08:00
|
|
|
| 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. |
|
1999-04-08 02:10:10 +08:00
|
|
|
+----------------------------------------------------------------------+
|
|
|
|
| Authors: Andi Gutmans <andi@zend.com> |
|
|
|
|
| Zeev Suraski <zeev@zend.com> |
|
|
|
|
+----------------------------------------------------------------------+
|
|
|
|
*/
|
|
|
|
|
2003-02-01 09:49:15 +08:00
|
|
|
/* $Id$ */
|
1999-04-08 02:18:16 +08:00
|
|
|
|
1999-04-08 02:10:10 +08:00
|
|
|
#include "zend.h"
|
|
|
|
#include "zend_extensions.h"
|
2001-02-27 02:18:34 +08:00
|
|
|
#include "zend_modules.h"
|
1999-04-08 02:10:10 +08:00
|
|
|
#include "zend_constants.h"
|
|
|
|
#include "zend_list.h"
|
1999-06-11 18:44:26 +08:00
|
|
|
#include "zend_API.h"
|
2004-02-12 18:38:14 +08:00
|
|
|
#include "zend_exceptions.h"
|
1999-09-20 20:24:39 +08:00
|
|
|
#include "zend_builtin_functions.h"
|
2000-12-27 23:43:15 +08:00
|
|
|
#include "zend_ini.h"
|
2008-04-17 18:21:38 +08:00
|
|
|
#include "zend_vm.h"
|
2010-04-24 21:32:30 +08:00
|
|
|
#include "zend_dtrace.h"
|
2013-10-17 16:40:43 +08:00
|
|
|
#include "zend_virtual_cwd.h"
|
1999-04-08 02:10:10 +08:00
|
|
|
|
1999-04-21 11:49:09 +08:00
|
|
|
#ifdef ZTS
|
2007-11-03 03:40:39 +08:00
|
|
|
# define GLOBAL_FUNCTION_TABLE global_function_table
|
|
|
|
# define GLOBAL_CLASS_TABLE global_class_table
|
|
|
|
# define GLOBAL_CONSTANTS_TABLE global_constants_table
|
|
|
|
# define GLOBAL_AUTO_GLOBALS_TABLE global_auto_globals_table
|
1999-04-21 11:49:09 +08:00
|
|
|
#else
|
2007-11-03 03:40:39 +08:00
|
|
|
# define GLOBAL_FUNCTION_TABLE CG(function_table)
|
|
|
|
# define GLOBAL_CLASS_TABLE CG(class_table)
|
|
|
|
# define GLOBAL_AUTO_GLOBALS_TABLE CG(auto_globals)
|
|
|
|
# define GLOBAL_CONSTANTS_TABLE EG(zend_constants)
|
1999-04-21 11:49:09 +08:00
|
|
|
#endif
|
|
|
|
|
1999-04-08 02:10:10 +08:00
|
|
|
/* true multithread-shared globals */
|
2002-03-12 18:08:47 +08:00
|
|
|
ZEND_API zend_class_entry *zend_standard_class_def = NULL;
|
2014-08-26 01:24:55 +08:00
|
|
|
ZEND_API size_t (*zend_printf)(const char *format, ...);
|
2000-03-26 03:10:07 +08:00
|
|
|
ZEND_API zend_write_func_t zend_write;
|
2015-03-04 07:05:28 +08:00
|
|
|
ZEND_API FILE *(*zend_fopen)(const char *filename, zend_string **opened_path);
|
2014-12-14 06:06:14 +08:00
|
|
|
ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle);
|
1999-12-02 06:55:20 +08:00
|
|
|
ZEND_API void (*zend_block_interruptions)(void);
|
|
|
|
ZEND_API void (*zend_unblock_interruptions)(void);
|
2014-12-14 06:06:14 +08:00
|
|
|
ZEND_API void (*zend_ticks_function)(int ticks);
|
2000-06-19 00:02:32 +08:00
|
|
|
ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
|
2014-08-26 01:24:55 +08:00
|
|
|
size_t (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
|
2014-05-10 00:21:49 +08:00
|
|
|
zend_string *(*zend_vstrpprintf)(size_t max_len, const char *format, va_list ap);
|
2014-12-14 06:06:14 +08:00
|
|
|
ZEND_API char *(*zend_getenv)(char *name, size_t name_len);
|
2015-03-04 07:05:28 +08:00
|
|
|
ZEND_API zend_string *(*zend_resolve_path)(const char *filename, int filename_len);
|
2000-06-19 00:02:32 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
void (*zend_on_timeout)(int seconds);
|
2002-09-19 23:58:01 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
static void (*zend_message_dispatcher_p)(zend_long message, const void *data);
|
2014-09-02 00:57:33 +08:00
|
|
|
static zval *(*zend_get_configuration_directive_p)(zend_string *name);
|
1999-06-20 04:42:15 +08:00
|
|
|
|
2007-11-03 03:40:39 +08:00
|
|
|
static ZEND_INI_MH(OnUpdateErrorReporting) /* {{{ */
|
2002-11-20 01:51:30 +08:00
|
|
|
{
|
|
|
|
if (!new_value) {
|
2008-02-24 01:06:22 +08:00
|
|
|
EG(error_reporting) = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED;
|
2002-11-20 01:51:30 +08:00
|
|
|
} else {
|
2015-06-30 18:59:27 +08:00
|
|
|
EG(error_reporting) = atoi(ZSTR_VAL(new_value));
|
2002-11-20 01:51:30 +08:00
|
|
|
}
|
|
|
|
return SUCCESS;
|
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
2002-11-20 01:51:30 +08:00
|
|
|
|
2008-01-22 17:27:48 +08:00
|
|
|
static ZEND_INI_MH(OnUpdateGCEnabled) /* {{{ */
|
|
|
|
{
|
2014-12-14 06:06:14 +08:00
|
|
|
OnUpdateBool(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
|
2008-01-22 17:27:48 +08:00
|
|
|
|
|
|
|
if (GC_G(gc_enabled)) {
|
2014-12-14 06:06:14 +08:00
|
|
|
gc_init();
|
2008-01-22 17:27:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return SUCCESS;
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
2010-12-20 00:36:37 +08:00
|
|
|
static ZEND_INI_MH(OnUpdateScriptEncoding) /* {{{ */
|
|
|
|
{
|
2014-12-24 00:33:30 +08:00
|
|
|
if (!CG(multibyte)) {
|
2010-12-20 00:36:37 +08:00
|
|
|
return FAILURE;
|
|
|
|
}
|
2014-12-14 06:06:14 +08:00
|
|
|
if (!zend_multibyte_get_functions()) {
|
2010-12-20 00:36:37 +08:00
|
|
|
return SUCCESS;
|
|
|
|
}
|
2015-06-30 18:59:27 +08:00
|
|
|
return zend_multibyte_set_script_encoding_by_string(new_value ? ZSTR_VAL(new_value) : NULL, new_value ? ZSTR_LEN(new_value) : 0);
|
2010-12-20 00:36:37 +08:00
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
2015-03-02 17:25:40 +08:00
|
|
|
static ZEND_INI_MH(OnUpdateAssertions) /* {{{ */
|
|
|
|
{
|
|
|
|
zend_long *p, val;
|
|
|
|
#ifndef ZTS
|
|
|
|
char *base = (char *) mh_arg2;
|
|
|
|
#else
|
|
|
|
char *base;
|
|
|
|
|
|
|
|
base = (char *) ts_resource(*((int *) mh_arg2));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
p = (zend_long *) (base+(size_t) mh_arg1);
|
|
|
|
|
2015-06-30 18:59:27 +08:00
|
|
|
val = zend_atol(ZSTR_VAL(new_value), (int)ZSTR_LEN(new_value));
|
2015-03-02 17:25:40 +08:00
|
|
|
|
|
|
|
if (stage != ZEND_INI_STAGE_STARTUP &&
|
|
|
|
stage != ZEND_INI_STAGE_SHUTDOWN &&
|
|
|
|
*p != val &&
|
|
|
|
(*p < 0 || val < 0)) {
|
|
|
|
zend_error(E_WARNING, "zend.assertions may be completely enabled or disabled only in php.ini");
|
|
|
|
return FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
*p = val;
|
|
|
|
return SUCCESS;
|
|
|
|
}
|
|
|
|
/* }}} */
|
2010-12-20 00:36:37 +08:00
|
|
|
|
2002-11-20 01:51:30 +08:00
|
|
|
ZEND_INI_BEGIN()
|
2004-02-25 18:57:10 +08:00
|
|
|
ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting)
|
2015-03-02 17:25:40 +08:00
|
|
|
STD_ZEND_INI_BOOLEAN("zend.assertions", "1", ZEND_INI_ALL, OnUpdateAssertions, assertions, zend_executor_globals, executor_globals)
|
2008-01-22 17:27:48 +08:00
|
|
|
STD_ZEND_INI_BOOLEAN("zend.enable_gc", "1", ZEND_INI_ALL, OnUpdateGCEnabled, gc_enabled, zend_gc_globals, gc_globals)
|
2010-11-24 13:41:23 +08:00
|
|
|
STD_ZEND_INI_BOOLEAN("zend.multibyte", "0", ZEND_INI_PERDIR, OnUpdateBool, multibyte, zend_compiler_globals, compiler_globals)
|
2010-12-20 00:36:37 +08:00
|
|
|
ZEND_INI_ENTRY("zend.script_encoding", NULL, ZEND_INI_ALL, OnUpdateScriptEncoding)
|
|
|
|
STD_ZEND_INI_BOOLEAN("zend.detect_unicode", "1", ZEND_INI_ALL, OnUpdateBool, detect_unicode, zend_compiler_globals, compiler_globals)
|
2011-06-22 22:23:21 +08:00
|
|
|
#ifdef ZEND_SIGNALS
|
|
|
|
STD_ZEND_INI_BOOLEAN("zend.signal_check", "0", ZEND_INI_SYSTEM, OnUpdateBool, check, zend_signal_globals_t, zend_signal_globals)
|
|
|
|
#endif
|
2002-11-20 01:51:30 +08:00
|
|
|
ZEND_INI_END()
|
|
|
|
|
|
|
|
|
1999-04-21 11:49:09 +08:00
|
|
|
#ifdef ZTS
|
reworked the patch, less new stuff but worky
TLS is already used in TSRM, the way exporting the tsrm cache through
a thread local variable is not portable. Additionally, the current
patch suffers from bugs which are hard to find, but prevent it to
be worky with apache. What is done here is mainly uses the idea
from the RFC patch, but
- __thread variable is removed
- offset math and declarations are removed
- extra macros and definitions are removed
What is done merely is
- use an inline function to access the tsrm cache. The function uses
the portable tsrm_tls_get macro which is cheap
- all the TSRM_* macros are set to placebo. Thus this opens the way
remove them later
Except that, the logic is old. TSRMLS_FETCH will have to be done once
per thread, then tsrm_get_ls_cache() can be used. Things seeming to be
worky are cli, cli server and apache. I also tried to enable bz2
shared and it has worked out of the box. The change is yet minimal
diffing to the current master bus is a worky start, IMHO. Though will
have to recheck the other previously done SAPIs - embed and cgi.
The offsets can be added to the tsrm_resource_type struct, then
it'll not be needed to declare them in the userspace. Even the
"done" member type can be changed to int16 or smaller, then adding
the offset as int16 will not change the struct size. As well on the
todo might be removing the hashed storage, thread_id != thread_id and
linked list logic in favour of the explicit TLS operations.
2014-09-26 00:48:27 +08:00
|
|
|
ZEND_API int compiler_globals_id;
|
|
|
|
ZEND_API int executor_globals_id;
|
2007-11-03 03:40:39 +08:00
|
|
|
static HashTable *global_function_table = NULL;
|
|
|
|
static HashTable *global_class_table = NULL;
|
|
|
|
static HashTable *global_constants_table = NULL;
|
|
|
|
static HashTable *global_auto_globals_table = NULL;
|
2005-09-12 17:06:15 +08:00
|
|
|
static HashTable *global_persistent_list = NULL;
|
2015-02-17 00:19:32 +08:00
|
|
|
ZEND_TSRMLS_CACHE_DEFINE();
|
1999-04-21 11:49:09 +08:00
|
|
|
#endif
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2002-09-03 18:25:06 +08:00
|
|
|
ZEND_API zend_utility_values zend_uv;
|
1999-04-08 02:10:10 +08:00
|
|
|
|
|
|
|
/* version information */
|
|
|
|
static char *zend_version_info;
|
|
|
|
static uint zend_version_info_length;
|
2015-01-15 23:27:30 +08:00
|
|
|
#define ZEND_CORE_VERSION_INFO "Zend Engine v" ZEND_VERSION ", Copyright (c) 1998-2015 Zend Technologies\n"
|
1999-12-22 01:14:31 +08:00
|
|
|
#define PRINT_ZVAL_INDENT 4
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
static void print_hash(zend_write_func_t write_func, HashTable *ht, int indent, zend_bool is_object) /* {{{ */
|
1999-04-08 02:10:10 +08:00
|
|
|
{
|
2014-02-10 14:04:30 +08:00
|
|
|
zval *tmp;
|
|
|
|
zend_string *string_key;
|
2014-08-26 01:24:55 +08:00
|
|
|
zend_ulong num_key;
|
1999-04-08 02:10:10 +08:00
|
|
|
int i;
|
|
|
|
|
2007-11-03 03:40:39 +08:00
|
|
|
for (i = 0; i < indent; i++) {
|
2009-02-18 18:55:08 +08:00
|
|
|
ZEND_PUTS_EX(" ");
|
1999-04-08 02:10:10 +08:00
|
|
|
}
|
2009-02-18 18:55:08 +08:00
|
|
|
ZEND_PUTS_EX("(\n");
|
1999-12-22 01:14:31 +08:00
|
|
|
indent += PRINT_ZVAL_INDENT;
|
2014-04-18 23:18:11 +08:00
|
|
|
ZEND_HASH_FOREACH_KEY_VAL(ht, num_key, string_key, tmp) {
|
2014-03-26 22:07:31 +08:00
|
|
|
if (Z_TYPE_P(tmp) == IS_INDIRECT) {
|
|
|
|
tmp = Z_INDIRECT_P(tmp);
|
|
|
|
if (Z_TYPE_P(tmp) == IS_UNDEF) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
for (i = 0; i < indent; i++) {
|
2009-02-18 18:55:08 +08:00
|
|
|
ZEND_PUTS_EX(" ");
|
1999-04-08 02:10:10 +08:00
|
|
|
}
|
2009-02-18 18:55:08 +08:00
|
|
|
ZEND_PUTS_EX("[");
|
2014-04-18 23:18:11 +08:00
|
|
|
if (string_key) {
|
|
|
|
if (is_object) {
|
|
|
|
const char *prop_name, *class_name;
|
2014-09-16 06:23:58 +08:00
|
|
|
size_t prop_len;
|
|
|
|
int mangled = zend_unmangle_property_name_ex(string_key, &class_name, &prop_name, &prop_len);
|
2014-04-18 23:18:11 +08:00
|
|
|
|
|
|
|
ZEND_WRITE_EX(prop_name, prop_len);
|
|
|
|
if (class_name && mangled == SUCCESS) {
|
|
|
|
if (class_name[0]=='*') {
|
|
|
|
ZEND_PUTS_EX(":protected");
|
|
|
|
} else {
|
|
|
|
ZEND_PUTS_EX(":");
|
|
|
|
ZEND_PUTS_EX(class_name);
|
|
|
|
ZEND_PUTS_EX(":private");
|
2003-06-09 02:53:58 +08:00
|
|
|
}
|
2009-02-18 18:55:08 +08:00
|
|
|
}
|
2014-04-18 23:18:11 +08:00
|
|
|
} else {
|
2015-06-30 18:59:27 +08:00
|
|
|
ZEND_WRITE_EX(ZSTR_VAL(string_key), ZSTR_LEN(string_key));
|
2014-04-18 23:18:11 +08:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
char key[25];
|
2014-08-26 02:22:49 +08:00
|
|
|
snprintf(key, sizeof(key), ZEND_LONG_FMT, num_key);
|
2014-04-18 23:18:11 +08:00
|
|
|
ZEND_PUTS_EX(key);
|
1999-04-08 02:10:10 +08:00
|
|
|
}
|
2009-02-18 18:55:08 +08:00
|
|
|
ZEND_PUTS_EX("] => ");
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_print_zval_r_ex(write_func, tmp, indent+PRINT_ZVAL_INDENT);
|
2009-02-18 18:55:08 +08:00
|
|
|
ZEND_PUTS_EX("\n");
|
2014-04-18 23:18:11 +08:00
|
|
|
} ZEND_HASH_FOREACH_END();
|
1999-12-22 01:14:31 +08:00
|
|
|
indent -= PRINT_ZVAL_INDENT;
|
2007-11-03 03:40:39 +08:00
|
|
|
for (i = 0; i < indent; i++) {
|
2009-02-18 18:55:08 +08:00
|
|
|
ZEND_PUTS_EX(" ");
|
1999-04-08 02:10:10 +08:00
|
|
|
}
|
2009-02-18 18:55:08 +08:00
|
|
|
ZEND_PUTS_EX(")\n");
|
1999-04-08 02:10:10 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
static void print_flat_hash(HashTable *ht) /* {{{ */
|
2002-12-02 03:47:02 +08:00
|
|
|
{
|
2014-02-10 14:04:30 +08:00
|
|
|
zval *tmp;
|
|
|
|
zend_string *string_key;
|
2014-08-26 01:24:55 +08:00
|
|
|
zend_ulong num_key;
|
2007-11-03 03:40:39 +08:00
|
|
|
int i = 0;
|
|
|
|
|
2014-05-26 02:07:29 +08:00
|
|
|
ZEND_HASH_FOREACH_KEY_VAL_IND(ht, num_key, string_key, tmp) {
|
2007-11-03 03:40:39 +08:00
|
|
|
if (i++ > 0) {
|
|
|
|
ZEND_PUTS(",");
|
|
|
|
}
|
|
|
|
ZEND_PUTS("[");
|
2014-04-18 23:18:11 +08:00
|
|
|
if (string_key) {
|
2015-06-30 18:59:27 +08:00
|
|
|
ZEND_WRITE(ZSTR_VAL(string_key), ZSTR_LEN(string_key));
|
2014-04-18 23:18:11 +08:00
|
|
|
} else {
|
2014-08-26 02:22:49 +08:00
|
|
|
zend_printf(ZEND_ULONG_FMT, num_key);
|
2007-11-03 03:40:39 +08:00
|
|
|
}
|
|
|
|
ZEND_PUTS("] => ");
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_print_flat_zval_r(tmp);
|
2014-04-18 23:18:11 +08:00
|
|
|
} ZEND_HASH_FOREACH_END();
|
2002-12-02 03:47:02 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-04-21 11:49:09 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
ZEND_API int zend_make_printable_zval(zval *expr, zval *expr_copy) /* {{{ */
|
1999-04-08 02:10:10 +08:00
|
|
|
{
|
2014-03-07 13:48:28 +08:00
|
|
|
if (Z_TYPE_P(expr) == IS_STRING) {
|
2014-07-09 20:05:55 +08:00
|
|
|
return 0;
|
2014-09-23 12:56:59 +08:00
|
|
|
} else {
|
2014-12-14 06:06:14 +08:00
|
|
|
ZVAL_STR(expr_copy, _zval_get_string_func(expr));
|
2014-09-23 12:56:59 +08:00
|
|
|
return 1;
|
1999-06-11 18:44:26 +08:00
|
|
|
}
|
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-06-11 18:44:26 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
ZEND_API size_t zend_print_zval(zval *expr, int indent) /* {{{ */
|
2000-03-26 03:10:07 +08:00
|
|
|
{
|
2014-12-14 06:06:14 +08:00
|
|
|
return zend_print_zval_ex(zend_write, expr, indent);
|
2000-03-26 03:10:07 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
2000-03-26 03:10:07 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
ZEND_API size_t zend_print_zval_ex(zend_write_func_t write_func, zval *expr, int indent) /* {{{ */
|
1999-06-11 18:44:26 +08:00
|
|
|
{
|
2014-04-22 02:36:01 +08:00
|
|
|
zend_string *str = zval_get_string(expr);
|
2015-06-30 18:59:27 +08:00
|
|
|
size_t len = ZSTR_LEN(str);
|
1999-06-11 18:44:26 +08:00
|
|
|
|
2014-04-21 23:12:10 +08:00
|
|
|
if (len != 0) {
|
2015-06-30 18:59:27 +08:00
|
|
|
write_func(ZSTR_VAL(str), len);
|
1999-04-08 02:10:10 +08:00
|
|
|
}
|
2014-04-21 23:12:10 +08:00
|
|
|
|
2014-08-26 01:24:55 +08:00
|
|
|
zend_string_release(str);
|
2014-04-21 23:12:10 +08:00
|
|
|
return len;
|
1999-04-08 02:10:10 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
ZEND_API void zend_print_flat_zval_r(zval *expr) /* {{{ */
|
2002-12-02 03:47:02 +08:00
|
|
|
{
|
2007-11-03 03:40:39 +08:00
|
|
|
switch (Z_TYPE_P(expr)) {
|
|
|
|
case IS_ARRAY:
|
|
|
|
ZEND_PUTS("Array (");
|
2014-05-29 22:21:56 +08:00
|
|
|
if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(expr)) &&
|
|
|
|
++Z_ARRVAL_P(expr)->u.v.nApplyCount>1) {
|
2007-11-03 03:40:39 +08:00
|
|
|
ZEND_PUTS(" *RECURSION*");
|
2014-04-21 22:25:34 +08:00
|
|
|
Z_ARRVAL_P(expr)->u.v.nApplyCount--;
|
2007-11-03 03:40:39 +08:00
|
|
|
return;
|
|
|
|
}
|
2014-12-14 06:06:14 +08:00
|
|
|
print_flat_hash(Z_ARRVAL_P(expr));
|
2007-11-03 03:40:39 +08:00
|
|
|
ZEND_PUTS(")");
|
2014-05-29 22:21:56 +08:00
|
|
|
if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(expr))) {
|
|
|
|
Z_ARRVAL_P(expr)->u.v.nApplyCount--;
|
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
break;
|
|
|
|
case IS_OBJECT:
|
|
|
|
{
|
2003-01-12 21:45:50 +08:00
|
|
|
HashTable *properties = NULL;
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_string *class_name = Z_OBJ_HANDLER_P(expr, get_class_name)(Z_OBJ_P(expr));
|
2015-06-30 18:59:27 +08:00
|
|
|
zend_printf("%s Object (", ZSTR_VAL(class_name));
|
2014-10-10 01:15:07 +08:00
|
|
|
zend_string_release(class_name);
|
2007-10-11 09:03:19 +08:00
|
|
|
|
2015-04-16 03:07:34 +08:00
|
|
|
if (Z_OBJ_APPLY_COUNT_P(expr) > 0) {
|
|
|
|
ZEND_PUTS(" *RECURSION*");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2003-01-14 20:13:51 +08:00
|
|
|
if (Z_OBJ_HANDLER_P(expr, get_properties)) {
|
2003-01-12 21:45:50 +08:00
|
|
|
properties = Z_OBJPROP_P(expr);
|
|
|
|
}
|
2003-01-14 20:13:51 +08:00
|
|
|
if (properties) {
|
2015-04-16 03:07:34 +08:00
|
|
|
Z_OBJ_INC_APPLY_COUNT_P(expr);
|
2014-12-14 06:06:14 +08:00
|
|
|
print_flat_hash(properties);
|
2015-04-16 03:07:34 +08:00
|
|
|
Z_OBJ_DEC_APPLY_COUNT_P(expr);
|
2003-01-12 21:45:50 +08:00
|
|
|
}
|
|
|
|
ZEND_PUTS(")");
|
|
|
|
break;
|
2007-11-03 03:40:39 +08:00
|
|
|
}
|
|
|
|
default:
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_print_variable(expr);
|
2007-11-03 03:40:39 +08:00
|
|
|
break;
|
|
|
|
}
|
2002-12-02 03:47:02 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
ZEND_API void zend_print_zval_r(zval *expr, int indent) /* {{{ */
|
2000-03-26 03:10:07 +08:00
|
|
|
{
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_print_zval_r_ex(zend_write, expr, indent);
|
2000-03-26 03:10:07 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
2000-03-26 03:10:07 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
ZEND_API void zend_print_zval_r_ex(zend_write_func_t write_func, zval *expr, int indent) /* {{{ */
|
1999-04-08 02:10:10 +08:00
|
|
|
{
|
2014-03-27 17:39:09 +08:00
|
|
|
ZVAL_DEREF(expr);
|
2007-11-03 03:40:39 +08:00
|
|
|
switch (Z_TYPE_P(expr)) {
|
1999-04-08 02:10:10 +08:00
|
|
|
case IS_ARRAY:
|
2009-02-18 18:55:08 +08:00
|
|
|
ZEND_PUTS_EX("Array\n");
|
2014-05-29 22:21:56 +08:00
|
|
|
if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(expr)) &&
|
|
|
|
++Z_ARRVAL_P(expr)->u.v.nApplyCount>1) {
|
2009-02-18 18:55:08 +08:00
|
|
|
ZEND_PUTS_EX(" *RECURSION*");
|
2014-04-21 22:25:34 +08:00
|
|
|
Z_ARRVAL_P(expr)->u.v.nApplyCount--;
|
2000-11-03 07:17:55 +08:00
|
|
|
return;
|
|
|
|
}
|
2014-12-14 06:06:14 +08:00
|
|
|
print_hash(write_func, Z_ARRVAL_P(expr), indent, 0);
|
2014-05-29 22:21:56 +08:00
|
|
|
if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(expr))) {
|
|
|
|
Z_ARRVAL_P(expr)->u.v.nApplyCount--;
|
|
|
|
}
|
1999-04-08 02:10:10 +08:00
|
|
|
break;
|
|
|
|
case IS_OBJECT:
|
2001-07-29 16:22:57 +08:00
|
|
|
{
|
2007-10-11 09:03:19 +08:00
|
|
|
HashTable *properties;
|
|
|
|
int is_temp;
|
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_string *class_name = Z_OBJ_HANDLER_P(expr, get_class_name)(Z_OBJ_P(expr));
|
2015-06-30 18:59:27 +08:00
|
|
|
ZEND_PUTS_EX(ZSTR_VAL(class_name));
|
2014-10-10 01:15:07 +08:00
|
|
|
zend_string_release(class_name);
|
|
|
|
|
2009-02-18 18:55:08 +08:00
|
|
|
ZEND_PUTS_EX(" Object\n");
|
2015-04-16 03:07:34 +08:00
|
|
|
if (Z_OBJ_APPLY_COUNT_P(expr) > 0) {
|
2009-02-18 18:55:08 +08:00
|
|
|
ZEND_PUTS_EX(" *RECURSION*");
|
2007-10-11 09:03:19 +08:00
|
|
|
return;
|
|
|
|
}
|
2015-04-16 03:07:34 +08:00
|
|
|
if ((properties = Z_OBJDEBUG_P(expr, is_temp)) == NULL) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
Z_OBJ_INC_APPLY_COUNT_P(expr);
|
2014-12-14 06:06:14 +08:00
|
|
|
print_hash(write_func, properties, indent, 1);
|
2015-04-16 03:07:34 +08:00
|
|
|
Z_OBJ_DEC_APPLY_COUNT_P(expr);
|
|
|
|
|
2007-10-11 09:03:19 +08:00
|
|
|
if (is_temp) {
|
|
|
|
zend_hash_destroy(properties);
|
2014-04-25 15:54:10 +08:00
|
|
|
FREE_HASHTABLE(properties);
|
2001-07-29 16:22:57 +08:00
|
|
|
}
|
|
|
|
break;
|
2000-11-03 07:17:55 +08:00
|
|
|
}
|
1999-04-08 02:10:10 +08:00
|
|
|
default:
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_print_zval_ex(write_func, expr, indent);
|
1999-04-08 02:10:10 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2015-03-04 07:05:28 +08:00
|
|
|
static FILE *zend_fopen_wrapper(const char *filename, zend_string **opened_path) /* {{{ */
|
1999-04-08 02:10:10 +08:00
|
|
|
{
|
1999-12-01 04:15:04 +08:00
|
|
|
if (opened_path) {
|
2015-03-04 07:05:28 +08:00
|
|
|
*opened_path = zend_string_init(filename, strlen(filename), 0);
|
1999-12-01 04:15:04 +08:00
|
|
|
}
|
2000-06-26 01:05:22 +08:00
|
|
|
return fopen(filename, "rb");
|
1999-04-08 02:10:10 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2007-01-12 22:37:46 +08:00
|
|
|
#ifdef ZTS
|
2014-09-10 05:14:19 +08:00
|
|
|
static zend_bool short_tags_default = 1;
|
2014-08-26 01:28:33 +08:00
|
|
|
static uint32_t compiler_options_default = ZEND_COMPILE_DEFAULT;
|
2007-01-12 22:37:46 +08:00
|
|
|
#else
|
2008-03-18 16:36:30 +08:00
|
|
|
# define short_tags_default 1
|
|
|
|
# define compiler_options_default ZEND_COMPILE_DEFAULT
|
2007-01-12 22:37:46 +08:00
|
|
|
#endif
|
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
static void zend_set_default_compile_time_values(void) /* {{{ */
|
2000-06-16 03:18:57 +08:00
|
|
|
{
|
|
|
|
/* default compile-time values */
|
2007-01-12 22:37:46 +08:00
|
|
|
CG(short_tags) = short_tags_default;
|
2008-03-18 16:36:30 +08:00
|
|
|
CG(compiler_options) = compiler_options_default;
|
2000-06-16 03:18:57 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
2000-06-16 03:18:57 +08:00
|
|
|
|
2015-04-06 04:45:58 +08:00
|
|
|
#ifdef ZEND_WIN32
|
2015-04-06 01:45:04 +08:00
|
|
|
static void zend_get_windows_version_info(OSVERSIONINFOEX *osvi) /* {{{ */
|
|
|
|
{
|
|
|
|
ZeroMemory(osvi, sizeof(OSVERSIONINFOEX));
|
|
|
|
osvi->dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
|
|
|
if(!GetVersionEx((OSVERSIONINFO *) osvi)) {
|
|
|
|
ZEND_ASSERT(0); /* Should not happen as sizeof is used. */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* }}} */
|
2015-04-06 04:45:58 +08:00
|
|
|
#endif
|
2015-04-06 01:45:04 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
static void zend_init_exception_op(void) /* {{{ */
|
2008-04-17 18:21:38 +08:00
|
|
|
{
|
|
|
|
memset(EG(exception_op), 0, sizeof(EG(exception_op)));
|
|
|
|
EG(exception_op)[0].opcode = ZEND_HANDLE_EXCEPTION;
|
2010-04-20 18:57:45 +08:00
|
|
|
EG(exception_op)[0].op1_type = IS_UNUSED;
|
|
|
|
EG(exception_op)[0].op2_type = IS_UNUSED;
|
|
|
|
EG(exception_op)[0].result_type = IS_UNUSED;
|
2008-04-17 18:21:38 +08:00
|
|
|
ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op));
|
|
|
|
EG(exception_op)[1].opcode = ZEND_HANDLE_EXCEPTION;
|
2010-04-20 18:57:45 +08:00
|
|
|
EG(exception_op)[1].op1_type = IS_UNUSED;
|
|
|
|
EG(exception_op)[1].op2_type = IS_UNUSED;
|
|
|
|
EG(exception_op)[1].result_type = IS_UNUSED;
|
2008-04-17 18:21:38 +08:00
|
|
|
ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op)+1);
|
|
|
|
EG(exception_op)[2].opcode = ZEND_HANDLE_EXCEPTION;
|
2010-04-20 18:57:45 +08:00
|
|
|
EG(exception_op)[2].op1_type = IS_UNUSED;
|
|
|
|
EG(exception_op)[2].op2_type = IS_UNUSED;
|
|
|
|
EG(exception_op)[2].result_type = IS_UNUSED;
|
2008-04-17 18:21:38 +08:00
|
|
|
ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op)+2);
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
2015-04-11 04:01:00 +08:00
|
|
|
static void zend_init_call_trampoline_op(void) /* {{{ */
|
|
|
|
{
|
|
|
|
memset(&EG(call_trampoline_op), 0, sizeof(EG(call_trampoline_op)));
|
|
|
|
EG(call_trampoline_op).opcode = ZEND_CALL_TRAMPOLINE;
|
|
|
|
EG(call_trampoline_op).op1_type = IS_UNUSED;
|
|
|
|
EG(call_trampoline_op).op2_type = IS_UNUSED;
|
|
|
|
EG(call_trampoline_op).result_type = IS_UNUSED;
|
|
|
|
ZEND_VM_SET_OPCODE_HANDLER(&EG(call_trampoline_op));
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
1999-04-21 11:49:09 +08:00
|
|
|
#ifdef ZTS
|
2014-04-10 03:40:01 +08:00
|
|
|
static void function_copy_ctor(zval *zv)
|
|
|
|
{
|
|
|
|
zend_function *old_func = Z_FUNC_P(zv);
|
|
|
|
Z_FUNC_P(zv) = pemalloc(sizeof(zend_internal_function), 1);
|
|
|
|
memcpy(Z_FUNC_P(zv), old_func, sizeof(zend_internal_function));
|
|
|
|
function_add_ref(Z_FUNC_P(zv));
|
|
|
|
}
|
|
|
|
|
2015-07-31 19:22:24 +08:00
|
|
|
static void auto_global_copy_ctor(zval *zv)
|
|
|
|
{
|
|
|
|
zend_auto_global *old_ag = (zend_auto_global *) Z_PTR_P(zv);
|
|
|
|
zend_auto_global *new_ag = pemalloc(sizeof(zend_auto_global), 1);
|
|
|
|
|
|
|
|
new_ag->name = zend_string_copy(old_ag->name);
|
|
|
|
new_ag->auto_global_callback = old_ag->auto_global_callback;
|
|
|
|
new_ag->jit = old_ag->jit;
|
|
|
|
|
|
|
|
Z_PTR_P(zv) = new_ag;
|
|
|
|
}
|
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
static void compiler_globals_ctor(zend_compiler_globals *compiler_globals) /* {{{ */
|
1999-04-21 11:49:09 +08:00
|
|
|
{
|
2000-07-13 00:37:46 +08:00
|
|
|
compiler_globals->compiled_filename = NULL;
|
|
|
|
|
2003-06-02 20:13:11 +08:00
|
|
|
compiler_globals->function_table = (HashTable *) malloc(sizeof(HashTable));
|
2014-04-21 22:25:34 +08:00
|
|
|
zend_hash_init_ex(compiler_globals->function_table, 1024, NULL, ZEND_FUNCTION_DTOR, 1, 0);
|
2014-04-10 03:40:01 +08:00
|
|
|
zend_hash_copy(compiler_globals->function_table, global_function_table, function_copy_ctor);
|
1999-04-21 11:49:09 +08:00
|
|
|
|
2007-11-03 03:40:39 +08:00
|
|
|
compiler_globals->class_table = (HashTable *) malloc(sizeof(HashTable));
|
2014-04-21 22:25:34 +08:00
|
|
|
zend_hash_init_ex(compiler_globals->class_table, 64, NULL, ZEND_CLASS_DTOR, 1, 0);
|
2014-02-17 21:59:18 +08:00
|
|
|
zend_hash_copy(compiler_globals->class_table, global_class_table, zend_class_add_ref);
|
1999-12-27 19:22:57 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_set_default_compile_time_values();
|
2001-07-15 22:08:58 +08:00
|
|
|
|
2001-08-09 01:18:16 +08:00
|
|
|
compiler_globals->auto_globals = (HashTable *) malloc(sizeof(HashTable));
|
|
|
|
zend_hash_init_ex(compiler_globals->auto_globals, 8, NULL, NULL, 1, 0);
|
2015-07-31 19:22:24 +08:00
|
|
|
zend_hash_copy(compiler_globals->auto_globals, global_auto_globals_table, auto_global_copy_ctor);
|
2005-12-01 19:48:17 +08:00
|
|
|
|
|
|
|
compiler_globals->last_static_member = zend_hash_num_elements(compiler_globals->class_table);
|
|
|
|
if (compiler_globals->last_static_member) {
|
2014-09-14 03:57:58 +08:00
|
|
|
compiler_globals->static_members_table = calloc(compiler_globals->last_static_member, sizeof(zval*));
|
2005-12-01 19:48:17 +08:00
|
|
|
} else {
|
2010-05-25 01:07:52 +08:00
|
|
|
compiler_globals->static_members_table = NULL;
|
2005-12-01 19:48:17 +08:00
|
|
|
}
|
2010-12-28 04:25:34 +08:00
|
|
|
compiler_globals->script_encoding_list = NULL;
|
2014-09-18 22:45:50 +08:00
|
|
|
|
|
|
|
#ifdef ZTS
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_interned_empty_string_init(&compiler_globals->empty_string);
|
2014-09-18 22:45:50 +08:00
|
|
|
|
|
|
|
memset(compiler_globals->one_char_string, 0, sizeof(compiler_globals->one_char_string));
|
|
|
|
#endif
|
1999-04-21 11:49:09 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-04-21 11:49:09 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
static void compiler_globals_dtor(zend_compiler_globals *compiler_globals) /* {{{ */
|
1999-04-21 11:49:09 +08:00
|
|
|
{
|
2001-12-13 04:45:38 +08:00
|
|
|
if (compiler_globals->function_table != GLOBAL_FUNCTION_TABLE) {
|
1999-05-11 04:46:42 +08:00
|
|
|
zend_hash_destroy(compiler_globals->function_table);
|
2003-12-12 18:50:23 +08:00
|
|
|
free(compiler_globals->function_table);
|
1999-05-11 04:46:42 +08:00
|
|
|
}
|
2001-12-13 04:45:38 +08:00
|
|
|
if (compiler_globals->class_table != GLOBAL_CLASS_TABLE) {
|
1999-05-11 04:46:42 +08:00
|
|
|
zend_hash_destroy(compiler_globals->class_table);
|
2003-12-12 18:50:23 +08:00
|
|
|
free(compiler_globals->class_table);
|
1999-05-11 04:46:42 +08:00
|
|
|
}
|
2003-12-12 18:50:23 +08:00
|
|
|
if (compiler_globals->auto_globals != GLOBAL_AUTO_GLOBALS_TABLE) {
|
2001-08-09 01:18:16 +08:00
|
|
|
zend_hash_destroy(compiler_globals->auto_globals);
|
|
|
|
free(compiler_globals->auto_globals);
|
|
|
|
}
|
2010-05-25 01:07:52 +08:00
|
|
|
if (compiler_globals->static_members_table) {
|
|
|
|
free(compiler_globals->static_members_table);
|
2005-12-01 19:48:17 +08:00
|
|
|
}
|
2010-12-20 00:36:37 +08:00
|
|
|
if (compiler_globals->script_encoding_list) {
|
2014-08-15 03:53:27 +08:00
|
|
|
pefree((char*)compiler_globals->script_encoding_list, 1);
|
2010-12-20 00:36:37 +08:00
|
|
|
}
|
2005-12-01 19:48:17 +08:00
|
|
|
compiler_globals->last_static_member = 0;
|
2014-09-18 22:45:50 +08:00
|
|
|
|
|
|
|
#ifdef ZTS
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_interned_empty_string_free(&compiler_globals->empty_string);
|
2014-09-18 22:45:50 +08:00
|
|
|
#endif
|
1999-04-21 11:49:09 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-04-22 01:26:37 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
static void executor_globals_ctor(zend_executor_globals *executor_globals) /* {{{ */
|
1999-04-22 01:26:37 +08:00
|
|
|
{
|
2015-02-17 00:19:32 +08:00
|
|
|
ZEND_TSRMLS_CACHE_UPDATE();
|
2015-02-21 11:35:16 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_startup_constants();
|
2002-09-19 06:16:22 +08:00
|
|
|
zend_copy_constants(EG(zend_constants), GLOBAL_CONSTANTS_TABLE);
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_init_rsrc_plist();
|
|
|
|
zend_init_exception_op();
|
2015-04-11 04:01:00 +08:00
|
|
|
zend_init_call_trampoline_op();
|
|
|
|
memset(&executor_globals->trampoline, 0, sizeof(zend_op_array));
|
2015-02-21 11:35:16 +08:00
|
|
|
executor_globals->lambda_count = 0;
|
|
|
|
ZVAL_UNDEF(&executor_globals->user_error_handler);
|
|
|
|
ZVAL_UNDEF(&executor_globals->user_exception_handler);
|
|
|
|
executor_globals->in_autoload = NULL;
|
|
|
|
executor_globals->current_execute_data = NULL;
|
|
|
|
executor_globals->current_module = NULL;
|
|
|
|
executor_globals->exit_status = 0;
|
2015-02-13 18:25:44 +08:00
|
|
|
#if XPFPA_HAVE_CW
|
2015-02-21 11:35:16 +08:00
|
|
|
executor_globals->saved_fpu_cw = 0;
|
2015-02-13 18:25:44 +08:00
|
|
|
#endif
|
2015-02-21 11:35:16 +08:00
|
|
|
executor_globals->saved_fpu_cw_ptr = NULL;
|
|
|
|
executor_globals->active = 0;
|
|
|
|
executor_globals->bailout = NULL;
|
|
|
|
executor_globals->error_handling = EH_NORMAL;
|
|
|
|
executor_globals->exception_class = NULL;
|
|
|
|
executor_globals->exception = NULL;
|
|
|
|
executor_globals->objects_store.object_buckets = NULL;
|
2015-04-05 02:28:58 +08:00
|
|
|
#ifdef ZEND_WIN32
|
2015-04-06 01:45:04 +08:00
|
|
|
zend_get_windows_version_info(&executor_globals->windows_version_info);
|
2015-04-05 02:28:58 +08:00
|
|
|
#endif
|
1999-04-22 01:26:37 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-04-22 01:26:37 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
static void executor_globals_dtor(zend_executor_globals *executor_globals) /* {{{ */
|
1999-04-22 01:26:37 +08:00
|
|
|
{
|
2014-12-16 17:15:02 +08:00
|
|
|
#ifdef ZTS
|
|
|
|
zend_ini_dtor(executor_globals->ini_directives);
|
|
|
|
#else
|
|
|
|
zend_ini_shutdown();
|
|
|
|
#endif
|
2005-09-12 17:06:15 +08:00
|
|
|
if (&executor_globals->persistent_list != global_persistent_list) {
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_destroy_rsrc_list(&executor_globals->persistent_list);
|
2005-09-12 17:06:15 +08:00
|
|
|
}
|
|
|
|
if (executor_globals->zend_constants != GLOBAL_CONSTANTS_TABLE) {
|
|
|
|
zend_hash_destroy(executor_globals->zend_constants);
|
|
|
|
free(executor_globals->zend_constants);
|
|
|
|
}
|
1999-04-22 01:26:37 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-04-22 01:26:37 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
static void zend_new_thread_end_handler(THREAD_T thread_id) /* {{{ */
|
2001-08-06 21:48:51 +08:00
|
|
|
{
|
2014-12-14 06:06:14 +08:00
|
|
|
if (zend_copy_ini_directives() == SUCCESS) {
|
|
|
|
zend_ini_refresh_caches(ZEND_INI_STAGE_STARTUP);
|
2006-11-08 19:04:27 +08:00
|
|
|
}
|
2001-08-06 21:48:51 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
2001-08-03 15:06:05 +08:00
|
|
|
#endif
|
|
|
|
|
2004-07-11 03:29:01 +08:00
|
|
|
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
|
|
|
/* FreeBSD and DragonFly floating point precision fix */
|
2000-06-12 01:45:19 +08:00
|
|
|
#include <floatingpoint.h>
|
|
|
|
#endif
|
1999-04-21 11:49:09 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
static void ini_scanner_globals_ctor(zend_ini_scanner_globals *scanner_globals_p) /* {{{ */
|
2008-03-17 05:06:55 +08:00
|
|
|
{
|
|
|
|
memset(scanner_globals_p, 0, sizeof(*scanner_globals_p));
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
static void php_scanner_globals_ctor(zend_php_scanner_globals *scanner_globals_p) /* {{{ */
|
2000-12-27 23:43:15 +08:00
|
|
|
{
|
2008-03-17 05:06:55 +08:00
|
|
|
memset(scanner_globals_p, 0, sizeof(*scanner_globals_p));
|
2000-12-27 23:43:15 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
2000-12-27 23:43:15 +08:00
|
|
|
|
2007-07-21 08:35:15 +08:00
|
|
|
void zend_init_opcodes_handlers(void);
|
2000-12-27 23:43:15 +08:00
|
|
|
|
2014-02-17 21:59:18 +08:00
|
|
|
static void module_destructor_zval(zval *zv) /* {{{ */
|
|
|
|
{
|
|
|
|
zend_module_entry *module = (zend_module_entry*)Z_PTR_P(zv);
|
|
|
|
|
|
|
|
module_destructor(module);
|
|
|
|
free(module);
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
|
|
|
static void auto_global_dtor(zval *zv) /* {{{ */
|
|
|
|
{
|
|
|
|
free(Z_PTR_P(zv));
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
static zend_bool php_auto_globals_create_globals(zend_string *name) /* {{{ */
|
2010-07-08 22:05:11 +08:00
|
|
|
{
|
2014-02-10 14:04:30 +08:00
|
|
|
zval globals;
|
|
|
|
|
|
|
|
ZVAL_ARR(&globals, &EG(symbol_table));
|
2015-02-14 03:20:39 +08:00
|
|
|
Z_TYPE_INFO_P(&globals) = IS_ARRAY | (IS_TYPE_SYMBOLTABLE << Z_TYPE_FLAGS_SHIFT);
|
2014-02-10 14:04:30 +08:00
|
|
|
ZVAL_NEW_REF(&globals, &globals);
|
2015-02-14 03:20:39 +08:00
|
|
|
zend_hash_update(&EG(symbol_table), name, &globals);
|
2010-07-08 22:05:11 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
int zend_startup(zend_utility_functions *utility_functions, char **extensions) /* {{{ */
|
1999-04-08 02:10:10 +08:00
|
|
|
{
|
1999-04-22 01:26:37 +08:00
|
|
|
#ifdef ZTS
|
1999-04-26 22:10:42 +08:00
|
|
|
zend_compiler_globals *compiler_globals;
|
1999-04-22 01:26:37 +08:00
|
|
|
zend_executor_globals *executor_globals;
|
reworked the patch, less new stuff but worky
TLS is already used in TSRM, the way exporting the tsrm cache through
a thread local variable is not portable. Additionally, the current
patch suffers from bugs which are hard to find, but prevent it to
be worky with apache. What is done here is mainly uses the idea
from the RFC patch, but
- __thread variable is removed
- offset math and declarations are removed
- extra macros and definitions are removed
What is done merely is
- use an inline function to access the tsrm cache. The function uses
the portable tsrm_tls_get macro which is cheap
- all the TSRM_* macros are set to placebo. Thus this opens the way
remove them later
Except that, the logic is old. TSRMLS_FETCH will have to be done once
per thread, then tsrm_get_ls_cache() can be used. Things seeming to be
worky are cli, cli server and apache. I also tried to enable bz2
shared and it has worked out of the box. The change is yet minimal
diffing to the current master bus is a worky start, IMHO. Though will
have to recheck the other previously done SAPIs - embed and cgi.
The offsets can be added to the tsrm_resource_type struct, then
it'll not be needed to declare them in the userspace. Even the
"done" member type can be changed to int16 or smaller, then adding
the offset as int16 will not change the struct size. As well on the
todo might be removing the hashed storage, thread_id != thread_id and
linked list logic in favour of the explicit TLS operations.
2014-09-26 00:48:27 +08:00
|
|
|
extern ZEND_API ts_rsrc_id ini_scanner_globals_id;
|
|
|
|
extern ZEND_API ts_rsrc_id language_scanner_globals_id;
|
2015-02-17 00:19:32 +08:00
|
|
|
ZEND_TSRMLS_CACHE_UPDATE();
|
2001-08-06 21:48:51 +08:00
|
|
|
#else
|
2008-03-17 05:06:55 +08:00
|
|
|
extern zend_ini_scanner_globals ini_scanner_globals;
|
|
|
|
extern zend_php_scanner_globals language_scanner_globals;
|
2001-08-06 21:48:51 +08:00
|
|
|
#endif
|
1999-04-22 01:26:37 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
start_memory_manager();
|
1999-04-22 01:26:37 +08:00
|
|
|
|
2013-10-17 16:40:43 +08:00
|
|
|
virtual_cwd_startup(); /* Could use shutdown to free the main cwd but it would just slow it down for CGI */
|
|
|
|
|
2004-07-11 03:29:01 +08:00
|
|
|
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
|
|
|
/* FreeBSD and DragonFly floating point precision fix */
|
2000-12-23 05:11:34 +08:00
|
|
|
fpsetmask(0);
|
2000-06-12 01:45:19 +08:00
|
|
|
#endif
|
2000-09-26 02:10:45 +08:00
|
|
|
|
2006-12-06 17:52:51 +08:00
|
|
|
zend_startup_strtod();
|
2000-09-26 02:10:45 +08:00
|
|
|
zend_startup_extensions_mechanism();
|
|
|
|
|
1999-04-08 02:10:10 +08:00
|
|
|
/* Set up utility functions and values */
|
2000-04-19 23:08:06 +08:00
|
|
|
zend_error_cb = utility_functions->error_function;
|
1999-04-08 02:10:10 +08:00
|
|
|
zend_printf = utility_functions->printf_function;
|
2000-03-26 03:10:07 +08:00
|
|
|
zend_write = (zend_write_func_t) utility_functions->write_function;
|
1999-04-08 02:10:10 +08:00
|
|
|
zend_fopen = utility_functions->fopen_function;
|
|
|
|
if (!zend_fopen) {
|
|
|
|
zend_fopen = zend_fopen_wrapper;
|
|
|
|
}
|
2003-02-18 17:37:54 +08:00
|
|
|
zend_stream_open_function = utility_functions->stream_open_function;
|
2000-03-06 03:50:10 +08:00
|
|
|
zend_message_dispatcher_p = utility_functions->message_handler;
|
2011-06-22 22:23:21 +08:00
|
|
|
#ifndef ZEND_SIGNALS
|
1999-04-08 02:10:10 +08:00
|
|
|
zend_block_interruptions = utility_functions->block_interruptions;
|
|
|
|
zend_unblock_interruptions = utility_functions->unblock_interruptions;
|
2011-06-22 22:23:21 +08:00
|
|
|
#endif
|
2001-01-08 02:39:11 +08:00
|
|
|
zend_get_configuration_directive_p = utility_functions->get_configuration_directive;
|
2000-01-25 03:00:30 +08:00
|
|
|
zend_ticks_function = utility_functions->ticks_function;
|
2002-09-19 23:58:01 +08:00
|
|
|
zend_on_timeout = utility_functions->on_timeout;
|
2003-08-31 17:35:54 +08:00
|
|
|
zend_vspprintf = utility_functions->vspprintf_function;
|
2014-05-10 00:21:49 +08:00
|
|
|
zend_vstrpprintf = utility_functions->vstrpprintf_function;
|
2004-09-06 06:40:35 +08:00
|
|
|
zend_getenv = utility_functions->getenv_function;
|
2008-03-05 21:34:12 +08:00
|
|
|
zend_resolve_path = utility_functions->resolve_path_function;
|
1999-06-20 04:42:15 +08:00
|
|
|
|
2010-04-24 21:32:30 +08:00
|
|
|
#if HAVE_DTRACE
|
|
|
|
/* build with dtrace support */
|
|
|
|
zend_compile_file = dtrace_compile_file;
|
2012-11-30 17:39:23 +08:00
|
|
|
zend_execute_ex = dtrace_execute_ex;
|
2010-04-24 21:32:30 +08:00
|
|
|
zend_execute_internal = dtrace_execute_internal;
|
|
|
|
#else
|
2000-08-10 03:22:35 +08:00
|
|
|
zend_compile_file = compile_file;
|
2012-11-30 17:39:23 +08:00
|
|
|
zend_execute_ex = execute_ex;
|
2003-01-12 00:12:44 +08:00
|
|
|
zend_execute_internal = NULL;
|
2010-04-24 21:32:30 +08:00
|
|
|
#endif /* HAVE_SYS_SDT_H */
|
|
|
|
zend_compile_string = compile_string;
|
2004-04-13 23:19:21 +08:00
|
|
|
zend_throw_exception_hook = NULL;
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-12-03 04:18:18 +08:00
|
|
|
/* Set up the default garbage collection implementation. */
|
|
|
|
gc_collect_cycles = zend_gc_collect_cycles;
|
|
|
|
|
2002-10-19 05:19:27 +08:00
|
|
|
zend_init_opcodes_handlers();
|
|
|
|
|
1999-04-08 02:10:10 +08:00
|
|
|
/* set up version */
|
|
|
|
zend_version_info = strdup(ZEND_CORE_VERSION_INFO);
|
2007-11-03 03:40:39 +08:00
|
|
|
zend_version_info_length = sizeof(ZEND_CORE_VERSION_INFO) - 1;
|
|
|
|
|
|
|
|
GLOBAL_FUNCTION_TABLE = (HashTable *) malloc(sizeof(HashTable));
|
|
|
|
GLOBAL_CLASS_TABLE = (HashTable *) malloc(sizeof(HashTable));
|
|
|
|
GLOBAL_AUTO_GLOBALS_TABLE = (HashTable *) malloc(sizeof(HashTable));
|
|
|
|
GLOBAL_CONSTANTS_TABLE = (HashTable *) malloc(sizeof(HashTable));
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-04-21 22:25:34 +08:00
|
|
|
zend_hash_init_ex(GLOBAL_FUNCTION_TABLE, 1024, NULL, ZEND_FUNCTION_DTOR, 1, 0);
|
|
|
|
zend_hash_init_ex(GLOBAL_CLASS_TABLE, 64, NULL, ZEND_CLASS_DTOR, 1, 0);
|
2014-02-17 21:59:18 +08:00
|
|
|
zend_hash_init_ex(GLOBAL_AUTO_GLOBALS_TABLE, 8, NULL, auto_global_dtor, 1, 0);
|
2014-04-21 22:25:34 +08:00
|
|
|
zend_hash_init_ex(GLOBAL_CONSTANTS_TABLE, 128, NULL, ZEND_CONSTANT_DTOR, 1, 0);
|
2001-10-01 01:29:55 +08:00
|
|
|
|
2014-04-21 22:25:34 +08:00
|
|
|
zend_hash_init_ex(&module_registry, 32, NULL, module_destructor_zval, 1, 0);
|
2000-04-15 21:02:22 +08:00
|
|
|
zend_init_rsrc_list_dtors();
|
1999-04-08 02:10:10 +08:00
|
|
|
|
1999-04-21 11:49:09 +08:00
|
|
|
#ifdef ZTS
|
reworked the patch, less new stuff but worky
TLS is already used in TSRM, the way exporting the tsrm cache through
a thread local variable is not portable. Additionally, the current
patch suffers from bugs which are hard to find, but prevent it to
be worky with apache. What is done here is mainly uses the idea
from the RFC patch, but
- __thread variable is removed
- offset math and declarations are removed
- extra macros and definitions are removed
What is done merely is
- use an inline function to access the tsrm cache. The function uses
the portable tsrm_tls_get macro which is cheap
- all the TSRM_* macros are set to placebo. Thus this opens the way
remove them later
Except that, the logic is old. TSRMLS_FETCH will have to be done once
per thread, then tsrm_get_ls_cache() can be used. Things seeming to be
worky are cli, cli server and apache. I also tried to enable bz2
shared and it has worked out of the box. The change is yet minimal
diffing to the current master bus is a worky start, IMHO. Though will
have to recheck the other previously done SAPIs - embed and cgi.
The offsets can be added to the tsrm_resource_type struct, then
it'll not be needed to declare them in the userspace. Even the
"done" member type can be changed to int16 or smaller, then adding
the offset as int16 will not change the struct size. As well on the
todo might be removing the hashed storage, thread_id != thread_id and
linked list logic in favour of the explicit TLS operations.
2014-09-26 00:48:27 +08:00
|
|
|
ts_allocate_id(&compiler_globals_id, sizeof(zend_compiler_globals), (ts_allocate_ctor) compiler_globals_ctor, (ts_allocate_dtor) compiler_globals_dtor);
|
|
|
|
ts_allocate_id(&executor_globals_id, sizeof(zend_executor_globals), (ts_allocate_ctor) executor_globals_ctor, (ts_allocate_dtor) executor_globals_dtor);
|
|
|
|
ts_allocate_id(&language_scanner_globals_id, sizeof(zend_php_scanner_globals), (ts_allocate_ctor) php_scanner_globals_ctor, NULL);
|
|
|
|
ts_allocate_id(&ini_scanner_globals_id, sizeof(zend_ini_scanner_globals), (ts_allocate_ctor) ini_scanner_globals_ctor, NULL);
|
1999-04-26 22:10:42 +08:00
|
|
|
compiler_globals = ts_resource(compiler_globals_id);
|
1999-04-22 01:26:37 +08:00
|
|
|
executor_globals = ts_resource(executor_globals_id);
|
2002-09-19 06:16:22 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
compiler_globals_dtor(compiler_globals);
|
2004-02-12 06:58:03 +08:00
|
|
|
compiler_globals->in_compilation = 0;
|
2003-12-12 18:50:23 +08:00
|
|
|
compiler_globals->function_table = (HashTable *) malloc(sizeof(HashTable));
|
|
|
|
compiler_globals->class_table = (HashTable *) malloc(sizeof(HashTable));
|
|
|
|
|
2001-12-14 00:55:04 +08:00
|
|
|
*compiler_globals->function_table = *GLOBAL_FUNCTION_TABLE;
|
|
|
|
*compiler_globals->class_table = *GLOBAL_CLASS_TABLE;
|
2001-08-09 01:18:16 +08:00
|
|
|
compiler_globals->auto_globals = GLOBAL_AUTO_GLOBALS_TABLE;
|
2002-09-19 06:16:22 +08:00
|
|
|
|
|
|
|
zend_hash_destroy(executor_globals->zend_constants);
|
|
|
|
*executor_globals->zend_constants = *GLOBAL_CONSTANTS_TABLE;
|
1999-07-15 03:49:19 +08:00
|
|
|
#else
|
2014-12-14 06:06:14 +08:00
|
|
|
ini_scanner_globals_ctor(&ini_scanner_globals);
|
|
|
|
php_scanner_globals_ctor(&language_scanner_globals);
|
|
|
|
zend_set_default_compile_time_values();
|
2015-05-29 17:44:46 +08:00
|
|
|
#ifdef ZEND_WIN32
|
|
|
|
zend_get_windows_version_info(&EG(windows_version_info));
|
|
|
|
#endif
|
1999-04-21 11:49:09 +08:00
|
|
|
#endif
|
2015-02-21 11:35:16 +08:00
|
|
|
EG(error_reporting) = E_ALL & ~E_NOTICE;
|
2008-12-31 04:15:28 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_interned_strings_init();
|
|
|
|
zend_startup_builtin_functions();
|
|
|
|
zend_register_standard_constants();
|
|
|
|
zend_register_auto_global(zend_string_init("GLOBALS", sizeof("GLOBALS") - 1, 1), 1, php_auto_globals_create_globals);
|
1999-04-21 11:49:09 +08:00
|
|
|
|
1999-05-09 20:24:21 +08:00
|
|
|
#ifndef ZTS
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_init_rsrc_plist();
|
|
|
|
zend_init_exception_op();
|
2015-04-11 04:01:00 +08:00
|
|
|
zend_init_call_trampoline_op();
|
1999-05-09 20:24:21 +08:00
|
|
|
#endif
|
1999-04-22 01:26:37 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_ini_startup();
|
2000-12-27 23:43:15 +08:00
|
|
|
|
|
|
|
#ifdef ZTS
|
|
|
|
tsrm_set_new_thread_end_handler(zend_new_thread_end_handler);
|
|
|
|
#endif
|
|
|
|
|
2015-03-05 18:11:22 +08:00
|
|
|
#ifdef ZEND_SIGNALS
|
|
|
|
zend_signal_startup();
|
|
|
|
#endif
|
|
|
|
|
1999-04-08 02:10:10 +08:00
|
|
|
return SUCCESS;
|
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
void zend_register_standard_ini_entries(void) /* {{{ */
|
2002-11-20 01:51:30 +08:00
|
|
|
{
|
|
|
|
int module_number = 0;
|
|
|
|
|
|
|
|
REGISTER_INI_ENTRIES();
|
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
2002-11-20 01:51:30 +08:00
|
|
|
|
2002-09-17 20:42:11 +08:00
|
|
|
/* Unlink the global (r/o) copies of the class, function and constant tables,
|
|
|
|
* and use a fresh r/w copy for the startup thread
|
|
|
|
*/
|
2014-12-14 06:06:14 +08:00
|
|
|
void zend_post_startup(void) /* {{{ */
|
2002-09-17 20:42:11 +08:00
|
|
|
{
|
2007-11-03 03:40:39 +08:00
|
|
|
#ifdef ZTS
|
2012-05-03 22:39:53 +08:00
|
|
|
zend_encoding **script_encoding_list;
|
|
|
|
|
2002-09-17 20:42:11 +08:00
|
|
|
zend_compiler_globals *compiler_globals = ts_resource(compiler_globals_id);
|
2002-09-19 06:16:22 +08:00
|
|
|
zend_executor_globals *executor_globals = ts_resource(executor_globals_id);
|
2002-09-17 20:42:11 +08:00
|
|
|
|
2002-09-19 06:16:22 +08:00
|
|
|
*GLOBAL_FUNCTION_TABLE = *compiler_globals->function_table;
|
|
|
|
*GLOBAL_CLASS_TABLE = *compiler_globals->class_table;
|
|
|
|
*GLOBAL_CONSTANTS_TABLE = *executor_globals->zend_constants;
|
2007-01-12 22:37:46 +08:00
|
|
|
|
|
|
|
short_tags_default = CG(short_tags);
|
2008-03-18 16:36:30 +08:00
|
|
|
compiler_options_default = CG(compiler_options);
|
2007-10-11 09:03:19 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_destroy_rsrc_list(&EG(persistent_list));
|
2003-12-12 18:50:23 +08:00
|
|
|
free(compiler_globals->function_table);
|
|
|
|
free(compiler_globals->class_table);
|
2012-05-03 22:39:53 +08:00
|
|
|
if ((script_encoding_list = (zend_encoding **)compiler_globals->script_encoding_list)) {
|
2014-12-14 06:06:14 +08:00
|
|
|
compiler_globals_ctor(compiler_globals);
|
2012-05-03 22:39:53 +08:00
|
|
|
compiler_globals->script_encoding_list = (const zend_encoding **)script_encoding_list;
|
|
|
|
} else {
|
2014-12-14 06:06:14 +08:00
|
|
|
compiler_globals_ctor(compiler_globals);
|
2012-05-03 22:39:53 +08:00
|
|
|
}
|
2003-12-12 18:50:23 +08:00
|
|
|
free(EG(zend_constants));
|
2013-10-17 16:40:43 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
virtual_cwd_deactivate();
|
2013-10-17 16:40:43 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
executor_globals_ctor(executor_globals);
|
2005-09-12 17:06:15 +08:00
|
|
|
global_persistent_list = &EG(persistent_list);
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_copy_ini_directives();
|
2013-10-17 16:40:43 +08:00
|
|
|
#else
|
2014-12-14 06:06:14 +08:00
|
|
|
virtual_cwd_deactivate();
|
2002-09-17 20:42:11 +08:00
|
|
|
#endif
|
2007-11-03 03:40:39 +08:00
|
|
|
}
|
|
|
|
/* }}} */
|
2002-09-17 20:42:11 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
void zend_shutdown(void) /* {{{ */
|
1999-04-08 02:10:10 +08:00
|
|
|
{
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_destroy_rsrc_list(&EG(persistent_list));
|
2014-09-02 06:08:02 +08:00
|
|
|
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) {
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_cleanup_user_class_data(ce);
|
2014-09-02 06:08:02 +08:00
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} ZEND_HASH_FOREACH_END();
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_cleanup_internal_classes();
|
|
|
|
zend_hash_reverse_apply(GLOBAL_FUNCTION_TABLE, (apply_func_t) clean_non_persistent_function_full);
|
|
|
|
zend_hash_reverse_apply(GLOBAL_CLASS_TABLE, (apply_func_t) clean_non_persistent_class_full);
|
2014-09-02 06:08:02 +08:00
|
|
|
}
|
2010-07-06 19:40:17 +08:00
|
|
|
zend_destroy_modules();
|
2001-12-24 02:39:52 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
virtual_cwd_deactivate();
|
2014-09-02 06:08:02 +08:00
|
|
|
virtual_cwd_shutdown();
|
2013-10-17 16:40:43 +08:00
|
|
|
|
1999-04-21 11:49:09 +08:00
|
|
|
zend_hash_destroy(GLOBAL_FUNCTION_TABLE);
|
2001-12-26 19:18:00 +08:00
|
|
|
zend_hash_destroy(GLOBAL_CLASS_TABLE);
|
2001-12-24 02:39:52 +08:00
|
|
|
|
2001-08-09 01:18:16 +08:00
|
|
|
zend_hash_destroy(GLOBAL_AUTO_GLOBALS_TABLE);
|
|
|
|
free(GLOBAL_AUTO_GLOBALS_TABLE);
|
2005-01-10 00:18:39 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_shutdown_extensions();
|
1999-04-08 02:10:10 +08:00
|
|
|
free(zend_version_info);
|
2003-04-19 02:40:53 +08:00
|
|
|
|
2003-12-12 19:14:44 +08:00
|
|
|
free(GLOBAL_FUNCTION_TABLE);
|
|
|
|
free(GLOBAL_CLASS_TABLE);
|
2005-09-12 17:06:15 +08:00
|
|
|
|
2003-04-19 02:40:53 +08:00
|
|
|
zend_hash_destroy(GLOBAL_CONSTANTS_TABLE);
|
2003-12-12 16:25:58 +08:00
|
|
|
free(GLOBAL_CONSTANTS_TABLE);
|
2006-12-06 17:52:51 +08:00
|
|
|
zend_shutdown_strtod();
|
2007-11-03 03:40:39 +08:00
|
|
|
|
2005-09-12 17:06:15 +08:00
|
|
|
#ifdef ZTS
|
2003-12-12 18:50:23 +08:00
|
|
|
GLOBAL_FUNCTION_TABLE = NULL;
|
|
|
|
GLOBAL_CLASS_TABLE = NULL;
|
|
|
|
GLOBAL_AUTO_GLOBALS_TABLE = NULL;
|
2005-09-12 17:06:15 +08:00
|
|
|
GLOBAL_CONSTANTS_TABLE = NULL;
|
2003-04-19 17:04:15 +08:00
|
|
|
#endif
|
2004-03-15 04:11:13 +08:00
|
|
|
zend_destroy_rsrc_list_dtors();
|
2010-04-20 19:05:54 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_interned_strings_dtor();
|
1999-04-08 02:10:10 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2007-11-03 03:40:39 +08:00
|
|
|
void zend_set_utility_values(zend_utility_values *utility_values) /* {{{ */
|
1999-04-10 19:21:55 +08:00
|
|
|
{
|
|
|
|
zend_uv = *utility_values;
|
2014-10-22 15:25:53 +08:00
|
|
|
zend_uv.import_use_extension_length = (uint)strlen(zend_uv.import_use_extension);
|
1999-04-10 19:21:55 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-04-10 19:21:55 +08:00
|
|
|
|
1999-04-08 02:10:10 +08:00
|
|
|
/* this should be compatible with the standard zenderror */
|
2008-08-13 01:20:25 +08:00
|
|
|
void zenderror(const char *error) /* {{{ */
|
1999-04-08 02:10:10 +08:00
|
|
|
{
|
2015-03-22 03:10:19 +08:00
|
|
|
if (EG(exception)) {
|
|
|
|
/* An exception was thrown in the lexer, don't throw another in the parser. */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-07-08 05:54:39 +08:00
|
|
|
zend_throw_exception(zend_ce_parse_error, error, 0);
|
1999-04-08 02:10:10 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-04-08 02:10:10 +08:00
|
|
|
|
1999-05-15 23:47:24 +08:00
|
|
|
BEGIN_EXTERN_C()
|
2007-11-03 03:40:39 +08:00
|
|
|
ZEND_API void _zend_bailout(char *filename, uint lineno) /* {{{ */
|
1999-04-08 02:10:10 +08:00
|
|
|
{
|
2014-10-15 15:37:55 +08:00
|
|
|
|
2006-05-19 14:09:15 +08:00
|
|
|
if (!EG(bailout)) {
|
2001-07-22 00:21:22 +08:00
|
|
|
zend_output_debug_string(1, "%s(%d) : Bailed out without a bailout address!", filename, lineno);
|
2001-07-21 22:25:27 +08:00
|
|
|
exit(-1);
|
|
|
|
}
|
1999-05-12 05:39:48 +08:00
|
|
|
CG(unclean_shutdown) = 1;
|
2011-06-08 06:58:38 +08:00
|
|
|
CG(active_class_entry) = NULL;
|
2014-07-03 05:02:25 +08:00
|
|
|
CG(in_compilation) = 0;
|
2002-08-28 22:43:32 +08:00
|
|
|
EG(current_execute_data) = NULL;
|
2008-03-19 05:14:28 +08:00
|
|
|
LONGJMP(*EG(bailout), FAILURE);
|
1999-04-08 02:10:10 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-05-15 23:47:24 +08:00
|
|
|
END_EXTERN_C()
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-10-13 01:22:03 +08:00
|
|
|
ZEND_API void zend_append_version_info(const zend_extension *extension) /* {{{ */
|
1999-04-08 02:10:10 +08:00
|
|
|
{
|
|
|
|
char *new_info;
|
|
|
|
uint new_info_length;
|
|
|
|
|
2014-10-22 15:25:53 +08:00
|
|
|
new_info_length = (uint)(sizeof(" with v, , by \n")
|
1999-04-08 02:10:10 +08:00
|
|
|
+ strlen(extension->name)
|
|
|
|
+ strlen(extension->version)
|
|
|
|
+ strlen(extension->copyright)
|
2014-10-22 15:25:53 +08:00
|
|
|
+ strlen(extension->author));
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2007-11-03 03:40:39 +08:00
|
|
|
new_info = (char *) malloc(new_info_length + 1);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2011-08-08 11:08:59 +08:00
|
|
|
snprintf(new_info, new_info_length, " with %s v%s, %s, by %s\n", extension->name, extension->version, extension->copyright, extension->author);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2007-11-03 03:40:39 +08:00
|
|
|
zend_version_info = (char *) realloc(zend_version_info, zend_version_info_length+new_info_length + 1);
|
2011-08-08 11:08:59 +08:00
|
|
|
strncat(zend_version_info, new_info, new_info_length);
|
1999-04-08 02:10:10 +08:00
|
|
|
zend_version_info_length += new_info_length;
|
|
|
|
free(new_info);
|
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2007-11-03 03:40:39 +08:00
|
|
|
ZEND_API char *get_zend_version(void) /* {{{ */
|
1999-04-08 02:10:10 +08:00
|
|
|
{
|
|
|
|
return zend_version_info;
|
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-06-06 04:00:00 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
ZEND_API void zend_activate(void) /* {{{ */
|
1999-06-06 04:00:00 +08:00
|
|
|
{
|
2013-11-02 20:32:31 +08:00
|
|
|
#ifdef ZTS
|
2014-12-14 06:06:14 +08:00
|
|
|
virtual_cwd_activate();
|
2013-11-02 20:32:31 +08:00
|
|
|
#endif
|
2014-12-14 06:06:14 +08:00
|
|
|
gc_reset();
|
|
|
|
init_compiler();
|
|
|
|
init_executor();
|
|
|
|
startup_scanner();
|
1999-06-06 04:00:00 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
1999-06-06 04:00:00 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
void zend_call_destructors(void) /* {{{ */
|
2004-07-25 15:14:49 +08:00
|
|
|
{
|
|
|
|
zend_try {
|
2014-12-14 06:06:14 +08:00
|
|
|
shutdown_destructors();
|
2004-07-25 15:14:49 +08:00
|
|
|
} zend_end_try();
|
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
2004-07-25 15:14:49 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
ZEND_API void zend_deactivate(void) /* {{{ */
|
1999-06-06 04:00:00 +08:00
|
|
|
{
|
2000-07-12 20:00:17 +08:00
|
|
|
/* we're no longer executing anything */
|
2014-07-03 03:29:53 +08:00
|
|
|
EG(current_execute_data) = NULL;
|
2000-04-24 20:47:07 +08:00
|
|
|
|
2001-07-21 22:25:27 +08:00
|
|
|
zend_try {
|
2014-12-14 06:06:14 +08:00
|
|
|
shutdown_scanner();
|
2001-07-21 22:25:27 +08:00
|
|
|
} zend_end_try();
|
|
|
|
|
2001-07-20 22:20:34 +08:00
|
|
|
/* shutdown_executor() takes care of its own bailout handling */
|
2014-12-14 06:06:14 +08:00
|
|
|
shutdown_executor();
|
2001-07-21 22:25:27 +08:00
|
|
|
|
|
|
|
zend_try {
|
2014-12-14 06:06:14 +08:00
|
|
|
shutdown_compiler();
|
2001-07-21 22:25:27 +08:00
|
|
|
} zend_end_try();
|
|
|
|
|
2015-02-22 00:19:06 +08:00
|
|
|
zend_destroy_rsrc_list(&EG(regular_list));
|
|
|
|
|
2008-01-24 18:42:12 +08:00
|
|
|
#if GC_BENCH
|
2008-01-29 04:34:02 +08:00
|
|
|
fprintf(stderr, "GC Statistics\n");
|
|
|
|
fprintf(stderr, "-------------\n");
|
|
|
|
fprintf(stderr, "Runs: %d\n", GC_G(gc_runs));
|
|
|
|
fprintf(stderr, "Collected: %d\n", GC_G(collected));
|
|
|
|
fprintf(stderr, "Root buffer length: %d\n", GC_G(root_buf_length));
|
|
|
|
fprintf(stderr, "Root buffer peak: %d\n\n", GC_G(root_buf_peak));
|
|
|
|
fprintf(stderr, " Possible Remove from Marked\n");
|
|
|
|
fprintf(stderr, " Root Buffered buffer grey\n");
|
|
|
|
fprintf(stderr, " -------- -------- ----------- ------\n");
|
|
|
|
fprintf(stderr, "ZVAL %8d %8d %9d %8d\n", GC_G(zval_possible_root), GC_G(zval_buffered), GC_G(zval_remove_from_buffer), GC_G(zval_marked_grey));
|
|
|
|
fprintf(stderr, "ZOBJ %8d %8d %9d %8d\n", GC_G(zobj_possible_root), GC_G(zobj_buffered), GC_G(zobj_remove_from_buffer), GC_G(zobj_marked_grey));
|
2008-01-24 18:42:12 +08:00
|
|
|
#endif
|
|
|
|
|
2001-07-21 22:25:27 +08:00
|
|
|
zend_try {
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_ini_deactivate();
|
2001-07-21 22:25:27 +08:00
|
|
|
} zend_end_try();
|
1999-06-06 04:00:00 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
2000-03-06 03:50:10 +08:00
|
|
|
|
2000-03-06 18:46:40 +08:00
|
|
|
BEGIN_EXTERN_C()
|
2014-12-14 06:06:14 +08:00
|
|
|
ZEND_API void zend_message_dispatcher(zend_long message, const void *data) /* {{{ */
|
2000-03-06 03:50:10 +08:00
|
|
|
{
|
|
|
|
if (zend_message_dispatcher_p) {
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_message_dispatcher_p(message, data);
|
2000-03-06 03:50:10 +08:00
|
|
|
}
|
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
2000-03-06 18:46:40 +08:00
|
|
|
END_EXTERN_C()
|
2000-03-06 03:50:10 +08:00
|
|
|
|
2014-09-02 00:57:33 +08:00
|
|
|
ZEND_API zval *zend_get_configuration_directive(zend_string *name) /* {{{ */
|
2000-03-06 03:50:10 +08:00
|
|
|
{
|
2001-01-08 02:39:11 +08:00
|
|
|
if (zend_get_configuration_directive_p) {
|
2014-09-02 00:57:33 +08:00
|
|
|
return zend_get_configuration_directive_p(name);
|
2000-03-06 03:50:10 +08:00
|
|
|
} else {
|
2014-09-02 00:57:33 +08:00
|
|
|
return NULL;
|
2000-03-06 03:50:10 +08:00
|
|
|
}
|
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
2000-04-19 23:08:06 +08:00
|
|
|
|
2011-08-02 15:38:23 +08:00
|
|
|
#define SAVE_STACK(stack) do { \
|
|
|
|
if (CG(stack).top) { \
|
|
|
|
memcpy(&stack, &CG(stack), sizeof(zend_stack)); \
|
|
|
|
CG(stack).top = CG(stack).max = 0; \
|
|
|
|
CG(stack).elements = NULL; \
|
|
|
|
} else { \
|
|
|
|
stack.top = 0; \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#define RESTORE_STACK(stack) do { \
|
|
|
|
if (stack.top) { \
|
|
|
|
zend_stack_destroy(&CG(stack)); \
|
|
|
|
memcpy(&CG(stack), &stack, sizeof(zend_stack)); \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
2015-02-06 21:13:16 +08:00
|
|
|
#if !defined(HAVE_NORETURN) || defined(HAVE_NORETURN_ALIAS)
|
2007-11-03 03:40:39 +08:00
|
|
|
ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
|
2014-09-09 02:34:26 +08:00
|
|
|
#else
|
|
|
|
static void zend_error_va_list(int type, const char *format, va_list args)
|
|
|
|
#endif
|
2000-04-19 23:08:06 +08:00
|
|
|
{
|
2014-02-10 14:04:30 +08:00
|
|
|
char *str;
|
|
|
|
int len;
|
2015-02-06 21:13:16 +08:00
|
|
|
#if !defined(HAVE_NORETURN) || defined(HAVE_NORETURN_ALIAS)
|
2000-04-19 23:08:06 +08:00
|
|
|
va_list args;
|
2014-09-09 02:34:26 +08:00
|
|
|
#endif
|
2004-12-06 23:50:27 +08:00
|
|
|
va_list usr_copy;
|
2014-02-10 14:04:30 +08:00
|
|
|
zval params[5];
|
|
|
|
zval retval;
|
2011-09-13 21:29:35 +08:00
|
|
|
const char *error_filename;
|
2014-04-22 21:46:34 +08:00
|
|
|
uint error_lineno = 0;
|
2014-02-10 14:04:30 +08:00
|
|
|
zval orig_user_error_handler;
|
2007-01-12 00:47:32 +08:00
|
|
|
zend_bool in_compilation;
|
|
|
|
zend_class_entry *saved_class_entry;
|
2015-07-10 08:31:52 +08:00
|
|
|
zend_stack loop_var_stack;
|
2014-08-15 23:10:06 +08:00
|
|
|
zend_stack delayed_oplines_stack;
|
2014-07-04 22:03:45 +08:00
|
|
|
zend_array *symbol_table;
|
2000-04-19 23:08:06 +08:00
|
|
|
|
2012-09-06 15:26:40 +08:00
|
|
|
/* Report about uncaught exception in case of fatal errors */
|
|
|
|
if (EG(exception)) {
|
2014-07-03 03:29:53 +08:00
|
|
|
zend_execute_data *ex;
|
2014-08-28 06:44:06 +08:00
|
|
|
const zend_op *opline;
|
2014-07-03 03:29:53 +08:00
|
|
|
|
2012-09-06 15:26:40 +08:00
|
|
|
switch (type) {
|
|
|
|
case E_CORE_ERROR:
|
|
|
|
case E_ERROR:
|
|
|
|
case E_RECOVERABLE_ERROR:
|
|
|
|
case E_PARSE:
|
|
|
|
case E_COMPILE_ERROR:
|
|
|
|
case E_USER_ERROR:
|
2014-07-03 03:29:53 +08:00
|
|
|
ex = EG(current_execute_data);
|
|
|
|
opline = NULL;
|
|
|
|
while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
|
|
|
|
ex = ex->prev_execute_data;
|
|
|
|
}
|
2014-07-07 19:50:44 +08:00
|
|
|
if (ex && ex->opline->opcode == ZEND_HANDLE_EXCEPTION &&
|
2014-07-03 03:29:53 +08:00
|
|
|
EG(opline_before_exception)) {
|
|
|
|
opline = EG(opline_before_exception);
|
2012-09-06 15:26:40 +08:00
|
|
|
}
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_exception_error(EG(exception), E_WARNING);
|
2012-09-06 15:26:40 +08:00
|
|
|
EG(exception) = NULL;
|
2014-07-03 03:29:53 +08:00
|
|
|
if (opline) {
|
|
|
|
ex->opline = opline;
|
2012-09-06 15:26:40 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-04-28 03:38:11 +08:00
|
|
|
/* Obtain relevant filename and lineno */
|
|
|
|
switch (type) {
|
|
|
|
case E_CORE_ERROR:
|
|
|
|
case E_CORE_WARNING:
|
|
|
|
error_filename = NULL;
|
|
|
|
error_lineno = 0;
|
|
|
|
break;
|
|
|
|
case E_PARSE:
|
|
|
|
case E_COMPILE_ERROR:
|
|
|
|
case E_COMPILE_WARNING:
|
|
|
|
case E_ERROR:
|
|
|
|
case E_NOTICE:
|
2003-11-18 17:25:04 +08:00
|
|
|
case E_STRICT:
|
2008-02-24 01:06:22 +08:00
|
|
|
case E_DEPRECATED:
|
2000-04-28 03:38:11 +08:00
|
|
|
case E_WARNING:
|
|
|
|
case E_USER_ERROR:
|
|
|
|
case E_USER_WARNING:
|
|
|
|
case E_USER_NOTICE:
|
2008-07-21 17:41:00 +08:00
|
|
|
case E_USER_DEPRECATED:
|
2006-05-10 22:04:18 +08:00
|
|
|
case E_RECOVERABLE_ERROR:
|
2014-12-14 06:06:14 +08:00
|
|
|
if (zend_is_compiling()) {
|
2015-06-30 18:59:27 +08:00
|
|
|
error_filename = ZSTR_VAL(zend_get_compiled_filename());
|
2014-12-14 06:06:14 +08:00
|
|
|
error_lineno = zend_get_compiled_lineno();
|
|
|
|
} else if (zend_is_executing()) {
|
|
|
|
error_filename = zend_get_executed_filename();
|
2014-07-03 05:02:25 +08:00
|
|
|
if (error_filename[0] == '[') { /* [no active file] */
|
|
|
|
error_filename = NULL;
|
|
|
|
error_lineno = 0;
|
|
|
|
} else {
|
2014-12-14 06:06:14 +08:00
|
|
|
error_lineno = zend_get_executed_lineno();
|
2014-07-03 05:02:25 +08:00
|
|
|
}
|
2000-04-28 03:38:11 +08:00
|
|
|
} else {
|
|
|
|
error_filename = NULL;
|
|
|
|
error_lineno = 0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
error_filename = NULL;
|
|
|
|
error_lineno = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!error_filename) {
|
|
|
|
error_filename = "Unknown";
|
|
|
|
}
|
2000-04-19 23:08:06 +08:00
|
|
|
|
2010-04-24 21:32:30 +08:00
|
|
|
#ifdef HAVE_DTRACE
|
2015-02-07 11:27:42 +08:00
|
|
|
if (DTRACE_ERROR_ENABLED()) {
|
2010-04-24 21:32:30 +08:00
|
|
|
char *dtrace_error_buffer;
|
2015-02-07 11:27:42 +08:00
|
|
|
#if !defined(HAVE_NORETURN) || defined(HAVE_NORETURN_ALIAS)
|
2013-08-19 08:20:56 +08:00
|
|
|
va_start(args, format);
|
2015-02-07 11:27:42 +08:00
|
|
|
#endif
|
2010-04-24 21:32:30 +08:00
|
|
|
zend_vspprintf(&dtrace_error_buffer, 0, format, args);
|
2013-08-14 11:42:39 +08:00
|
|
|
DTRACE_ERROR(dtrace_error_buffer, (char *)error_filename, error_lineno);
|
2010-04-24 21:32:30 +08:00
|
|
|
efree(dtrace_error_buffer);
|
2015-02-07 11:27:42 +08:00
|
|
|
#if !defined(HAVE_NORETURN) || defined(HAVE_NORETURN_ALIAS)
|
2013-08-19 08:20:56 +08:00
|
|
|
va_end(args);
|
2015-02-07 11:27:42 +08:00
|
|
|
#endif
|
2010-04-24 21:32:30 +08:00
|
|
|
}
|
|
|
|
#endif /* HAVE_DTRACE */
|
|
|
|
|
2015-02-06 21:13:16 +08:00
|
|
|
#if !defined(HAVE_NORETURN) || defined(HAVE_NORETURN_ALIAS)
|
2013-08-19 08:20:56 +08:00
|
|
|
va_start(args, format);
|
2014-09-09 02:34:26 +08:00
|
|
|
#endif
|
2013-08-19 08:20:56 +08:00
|
|
|
|
2000-04-19 23:08:06 +08:00
|
|
|
/* if we don't have a user defined error handler */
|
2014-02-10 14:04:30 +08:00
|
|
|
if (Z_TYPE(EG(user_error_handler)) == IS_UNDEF
|
2008-03-09 05:54:03 +08:00
|
|
|
|| !(EG(user_error_handler_error_reporting) & type)
|
|
|
|
|| EG(error_handling) != EH_NORMAL) {
|
2000-04-28 03:38:11 +08:00
|
|
|
zend_error_cb(type, error_filename, error_lineno, format, args);
|
|
|
|
} else switch (type) {
|
2000-04-19 23:08:06 +08:00
|
|
|
case E_ERROR:
|
|
|
|
case E_PARSE:
|
|
|
|
case E_CORE_ERROR:
|
|
|
|
case E_CORE_WARNING:
|
|
|
|
case E_COMPILE_ERROR:
|
|
|
|
case E_COMPILE_WARNING:
|
2000-04-28 03:38:11 +08:00
|
|
|
/* The error may not be safe to handle in user-space */
|
|
|
|
zend_error_cb(type, error_filename, error_lineno, format, args);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* Handle the error in user space */
|
2005-06-28 06:04:41 +08:00
|
|
|
/* va_copy() is __va_copy() in old gcc versions.
|
|
|
|
* According to the autoconf manual, using
|
|
|
|
* memcpy(&dst, &src, sizeof(va_list))
|
|
|
|
* gives maximum portability. */
|
|
|
|
#ifndef va_copy
|
|
|
|
# ifdef __va_copy
|
|
|
|
# define va_copy(dest, src) __va_copy((dest), (src))
|
|
|
|
# else
|
|
|
|
# define va_copy(dest, src) memcpy(&(dest), &(src), sizeof(va_list))
|
|
|
|
# endif
|
2004-12-06 23:50:27 +08:00
|
|
|
#endif
|
2005-06-28 06:04:41 +08:00
|
|
|
va_copy(usr_copy, args);
|
2014-10-22 15:25:53 +08:00
|
|
|
len = (int)zend_vspprintf(&str, 0, format, usr_copy);
|
2014-08-26 01:24:55 +08:00
|
|
|
ZVAL_NEW_STR(¶ms[1], zend_string_init(str, len, 0));
|
2014-02-10 14:04:30 +08:00
|
|
|
efree(str);
|
2005-06-28 06:04:41 +08:00
|
|
|
#ifdef va_copy
|
2004-12-06 23:50:27 +08:00
|
|
|
va_end(usr_copy);
|
|
|
|
#endif
|
2000-04-19 23:08:06 +08:00
|
|
|
|
2014-02-10 14:04:30 +08:00
|
|
|
ZVAL_LONG(¶ms[0], type);
|
2000-04-19 23:08:06 +08:00
|
|
|
|
2000-06-29 06:08:47 +08:00
|
|
|
if (error_filename) {
|
2014-02-10 14:04:30 +08:00
|
|
|
ZVAL_STRING(¶ms[2], error_filename);
|
|
|
|
} else {
|
|
|
|
ZVAL_NULL(¶ms[2]);
|
2000-06-29 06:08:47 +08:00
|
|
|
}
|
2003-01-12 20:39:06 +08:00
|
|
|
|
2014-02-10 14:04:30 +08:00
|
|
|
ZVAL_LONG(¶ms[3], error_lineno);
|
2000-06-29 06:08:47 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
symbol_table = zend_rebuild_symbol_table();
|
2009-10-27 21:02:36 +08:00
|
|
|
|
|
|
|
/* during shutdown the symbol table table can be still null */
|
2014-07-04 22:03:45 +08:00
|
|
|
if (!symbol_table) {
|
2014-02-10 14:04:30 +08:00
|
|
|
ZVAL_NULL(¶ms[4]);
|
2009-10-27 21:02:36 +08:00
|
|
|
} else {
|
2015-02-14 03:20:39 +08:00
|
|
|
ZVAL_ARR(¶ms[4], zend_array_dup(symbol_table));
|
2009-10-27 21:02:36 +08:00
|
|
|
}
|
2000-06-29 23:07:59 +08:00
|
|
|
|
2014-02-10 14:04:30 +08:00
|
|
|
ZVAL_COPY_VALUE(&orig_user_error_handler, &EG(user_error_handler));
|
|
|
|
ZVAL_UNDEF(&EG(user_error_handler));
|
2007-10-11 09:03:19 +08:00
|
|
|
|
2007-01-12 00:47:32 +08:00
|
|
|
/* User error handler may include() additinal PHP files.
|
|
|
|
* If an error was generated during comilation PHP will compile
|
2007-10-11 09:03:19 +08:00
|
|
|
* such scripts recursivly, but some CG() variables may be
|
|
|
|
* inconsistent. */
|
2007-01-12 00:47:32 +08:00
|
|
|
|
2013-09-29 23:58:25 +08:00
|
|
|
in_compilation = CG(in_compilation);
|
2007-01-12 00:47:32 +08:00
|
|
|
if (in_compilation) {
|
|
|
|
saved_class_entry = CG(active_class_entry);
|
|
|
|
CG(active_class_entry) = NULL;
|
2015-07-10 08:31:52 +08:00
|
|
|
SAVE_STACK(loop_var_stack);
|
2014-08-15 23:10:06 +08:00
|
|
|
SAVE_STACK(delayed_oplines_stack);
|
2013-09-29 23:58:25 +08:00
|
|
|
CG(in_compilation) = 0;
|
2007-01-12 00:47:32 +08:00
|
|
|
}
|
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
if (call_user_function_ex(CG(function_table), NULL, &orig_user_error_handler, &retval, 5, params, 1, NULL) == SUCCESS) {
|
2014-02-10 14:04:30 +08:00
|
|
|
if (Z_TYPE(retval) != IS_UNDEF) {
|
2014-04-30 22:32:42 +08:00
|
|
|
if (Z_TYPE(retval) == IS_FALSE) {
|
2004-05-29 01:28:33 +08:00
|
|
|
zend_error_cb(type, error_filename, error_lineno, format, args);
|
|
|
|
}
|
2002-11-25 04:15:56 +08:00
|
|
|
zval_ptr_dtor(&retval);
|
|
|
|
}
|
2006-03-28 06:07:38 +08:00
|
|
|
} else if (!EG(exception)) {
|
2000-04-28 03:38:11 +08:00
|
|
|
/* The user error handler failed, use built-in error handler */
|
|
|
|
zend_error_cb(type, error_filename, error_lineno, format, args);
|
|
|
|
}
|
2003-12-19 22:08:22 +08:00
|
|
|
|
2007-01-12 00:47:32 +08:00
|
|
|
if (in_compilation) {
|
|
|
|
CG(active_class_entry) = saved_class_entry;
|
2015-07-10 08:31:52 +08:00
|
|
|
RESTORE_STACK(loop_var_stack);
|
2014-08-15 23:10:06 +08:00
|
|
|
RESTORE_STACK(delayed_oplines_stack);
|
2013-09-29 23:58:25 +08:00
|
|
|
CG(in_compilation) = 1;
|
2007-01-12 00:47:32 +08:00
|
|
|
}
|
|
|
|
|
2014-02-25 17:35:39 +08:00
|
|
|
zval_ptr_dtor(¶ms[4]);
|
|
|
|
zval_ptr_dtor(¶ms[3]);
|
|
|
|
zval_ptr_dtor(¶ms[2]);
|
|
|
|
zval_ptr_dtor(¶ms[1]);
|
|
|
|
zval_ptr_dtor(¶ms[0]);
|
|
|
|
|
2014-02-10 14:04:30 +08:00
|
|
|
if (Z_TYPE(EG(user_error_handler)) == IS_UNDEF) {
|
|
|
|
ZVAL_COPY_VALUE(&EG(user_error_handler), &orig_user_error_handler);
|
2014-02-25 17:35:39 +08:00
|
|
|
} else {
|
2005-05-14 07:08:43 +08:00
|
|
|
zval_ptr_dtor(&orig_user_error_handler);
|
|
|
|
}
|
2000-04-28 03:38:11 +08:00
|
|
|
break;
|
2000-04-19 23:08:06 +08:00
|
|
|
}
|
2000-04-28 03:38:11 +08:00
|
|
|
|
2015-02-06 21:13:16 +08:00
|
|
|
#if !defined(HAVE_NORETURN) || defined(HAVE_NORETURN_ALIAS)
|
2000-04-28 03:38:11 +08:00
|
|
|
va_end(args);
|
2014-09-09 02:34:26 +08:00
|
|
|
#endif
|
2001-05-07 03:30:31 +08:00
|
|
|
|
2002-10-08 05:20:23 +08:00
|
|
|
if (type == E_PARSE) {
|
2013-01-02 12:14:44 +08:00
|
|
|
/* eval() errors do not affect exit_status */
|
|
|
|
if (!(EG(current_execute_data) &&
|
2014-07-07 19:50:44 +08:00
|
|
|
EG(current_execute_data)->func &&
|
|
|
|
ZEND_USER_CODE(EG(current_execute_data)->func->type) &&
|
2013-01-02 12:14:44 +08:00
|
|
|
EG(current_execute_data)->opline->opcode == ZEND_INCLUDE_OR_EVAL &&
|
|
|
|
EG(current_execute_data)->opline->extended_value == ZEND_EVAL)) {
|
|
|
|
EG(exit_status) = 255;
|
|
|
|
}
|
2001-05-07 03:30:31 +08:00
|
|
|
}
|
2000-04-19 23:08:06 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
2000-04-19 23:08:06 +08:00
|
|
|
|
2015-02-06 18:42:22 +08:00
|
|
|
#ifdef HAVE_NORETURN
|
|
|
|
# ifdef HAVE_NORETURN_ALIAS
|
2005-06-13 19:22:59 +08:00
|
|
|
void zend_error_noreturn(int type, const char *format, ...) __attribute__ ((alias("zend_error"),noreturn));
|
2015-02-06 18:42:22 +08:00
|
|
|
# else
|
2014-09-09 02:34:26 +08:00
|
|
|
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);
|
|
|
|
}
|
2014-09-20 13:51:58 +08:00
|
|
|
/* }}} */
|
2015-02-06 18:42:22 +08:00
|
|
|
# endif
|
2005-06-13 19:22:59 +08:00
|
|
|
#endif
|
2000-06-03 09:49:49 +08:00
|
|
|
|
2015-07-04 05:04:33 +08:00
|
|
|
ZEND_API void zend_throw_error(zend_class_entry *exception_ce, const char *format, ...) /* {{{ */
|
2015-07-04 02:41:17 +08:00
|
|
|
{
|
|
|
|
va_list va;
|
|
|
|
char *message = NULL;
|
2015-07-08 00:37:33 +08:00
|
|
|
|
|
|
|
if (exception_ce) {
|
|
|
|
if (!instanceof_function(exception_ce, zend_ce_error)) {
|
|
|
|
zend_error(E_NOTICE, "Error exceptions must be derived from Error");
|
|
|
|
exception_ce = zend_ce_error;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
exception_ce = zend_ce_error;
|
|
|
|
}
|
2015-07-04 05:04:33 +08:00
|
|
|
|
2015-07-04 02:41:17 +08:00
|
|
|
va_start(va, format);
|
|
|
|
zend_vspprintf(&message, 0, format, va);
|
|
|
|
|
2015-07-08 00:37:33 +08:00
|
|
|
//TODO: we can't convert compile-time errors to exceptions yet???
|
2015-07-04 05:04:33 +08:00
|
|
|
if (EG(current_execute_data) && !CG(in_compilation)) {
|
2015-07-04 06:28:11 +08:00
|
|
|
zend_throw_exception(exception_ce, message, 0);
|
2015-07-04 05:04:33 +08:00
|
|
|
} else {
|
|
|
|
zend_error(E_ERROR, message);
|
2015-07-04 02:41:17 +08:00
|
|
|
}
|
2015-07-04 05:04:33 +08:00
|
|
|
|
2015-07-04 02:41:17 +08:00
|
|
|
efree(message);
|
|
|
|
va_end(va);
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
2015-03-19 00:23:09 +08:00
|
|
|
ZEND_API void zend_type_error(const char *format, ...) /* {{{ */
|
|
|
|
{
|
|
|
|
va_list va;
|
|
|
|
char *message = NULL;
|
|
|
|
|
|
|
|
va_start(va, format);
|
|
|
|
zend_vspprintf(&message, 0, format, va);
|
2015-07-08 05:54:39 +08:00
|
|
|
zend_throw_exception(zend_ce_type_error, message, 0);
|
2015-03-19 00:23:09 +08:00
|
|
|
efree(message);
|
|
|
|
va_end(va);
|
|
|
|
} /* }}} */
|
|
|
|
|
2015-04-03 00:52:32 +08:00
|
|
|
ZEND_API void zend_internal_type_error(zend_bool throw_exception, const char *format, ...) /* {{{ */
|
2015-03-19 00:23:09 +08:00
|
|
|
{
|
|
|
|
va_list va;
|
|
|
|
char *message = NULL;
|
|
|
|
|
|
|
|
va_start(va, format);
|
|
|
|
zend_vspprintf(&message, 0, format, va);
|
2015-04-03 00:52:32 +08:00
|
|
|
if (throw_exception) {
|
2015-07-08 05:54:39 +08:00
|
|
|
zend_throw_exception(zend_ce_type_error, message, 0);
|
2015-03-19 00:23:09 +08:00
|
|
|
} else {
|
|
|
|
zend_error(E_WARNING, message);
|
|
|
|
}
|
|
|
|
efree(message);
|
|
|
|
|
|
|
|
va_end(va);
|
|
|
|
} /* }}} */
|
|
|
|
|
2008-08-13 01:20:25 +08:00
|
|
|
ZEND_API void zend_output_debug_string(zend_bool trigger_break, const char *format, ...) /* {{{ */
|
2000-06-03 09:49:49 +08:00
|
|
|
{
|
|
|
|
#if ZEND_DEBUG
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
va_start(args, format);
|
2000-06-03 15:34:20 +08:00
|
|
|
# ifdef ZEND_WIN32
|
2000-06-03 09:49:49 +08:00
|
|
|
{
|
|
|
|
char output_buf[1024];
|
|
|
|
|
|
|
|
vsnprintf(output_buf, 1024, format, args);
|
|
|
|
OutputDebugString(output_buf);
|
|
|
|
OutputDebugString("\n");
|
|
|
|
if (trigger_break && IsDebuggerPresent()) {
|
|
|
|
DebugBreak();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
# else
|
|
|
|
vfprintf(stderr, format, args);
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
# endif
|
|
|
|
va_end(args);
|
|
|
|
#endif
|
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
2000-08-10 03:22:35 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
ZEND_API int zend_execute_scripts(int type, zval *retval, int file_count, ...) /* {{{ */
|
2000-08-10 03:22:35 +08:00
|
|
|
{
|
|
|
|
va_list files;
|
|
|
|
int i;
|
|
|
|
zend_file_handle *file_handle;
|
2014-07-03 02:03:21 +08:00
|
|
|
zend_op_array *op_array;
|
2003-01-12 20:39:06 +08:00
|
|
|
|
2000-08-10 03:22:35 +08:00
|
|
|
va_start(files, file_count);
|
2007-11-03 03:40:39 +08:00
|
|
|
for (i = 0; i < file_count; i++) {
|
2000-08-10 03:22:35 +08:00
|
|
|
file_handle = va_arg(files, zend_file_handle *);
|
|
|
|
if (!file_handle) {
|
|
|
|
continue;
|
|
|
|
}
|
2015-01-03 17:22:58 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
op_array = zend_compile_file(file_handle, type);
|
2007-11-03 03:40:39 +08:00
|
|
|
if (file_handle->opened_path) {
|
2015-03-04 07:05:28 +08:00
|
|
|
zend_hash_add_empty_element(&EG(included_files), file_handle->opened_path);
|
2005-05-05 00:17:33 +08:00
|
|
|
}
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_destroy_file_handle(file_handle);
|
2014-07-03 02:03:21 +08:00
|
|
|
if (op_array) {
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_execute(op_array, retval);
|
|
|
|
zend_exception_restore();
|
2001-12-09 04:58:20 +08:00
|
|
|
if (EG(exception)) {
|
2014-02-10 14:04:30 +08:00
|
|
|
if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
|
|
|
|
zval orig_user_exception_handler;
|
|
|
|
zval params[1], retval2;
|
|
|
|
zend_object *old_exception;
|
2003-06-15 23:07:55 +08:00
|
|
|
old_exception = EG(exception);
|
2009-03-26 18:56:45 +08:00
|
|
|
EG(exception) = NULL;
|
2014-02-10 14:04:30 +08:00
|
|
|
ZVAL_OBJ(¶ms[0], old_exception);
|
|
|
|
ZVAL_COPY_VALUE(&orig_user_exception_handler, &EG(user_exception_handler));
|
2015-04-09 14:16:04 +08:00
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
if (call_user_function_ex(CG(function_table), NULL, &orig_user_exception_handler, &retval2, 1, params, 1, NULL) == SUCCESS) {
|
2014-02-10 14:04:30 +08:00
|
|
|
zval_ptr_dtor(&retval2);
|
2008-08-14 18:24:52 +08:00
|
|
|
if (EG(exception)) {
|
2014-02-14 21:48:45 +08:00
|
|
|
OBJ_RELEASE(EG(exception));
|
2008-08-14 18:24:52 +08:00
|
|
|
EG(exception) = NULL;
|
2007-03-16 00:44:12 +08:00
|
|
|
}
|
2014-02-14 21:48:45 +08:00
|
|
|
OBJ_RELEASE(old_exception);
|
2008-08-14 18:24:52 +08:00
|
|
|
} else {
|
2009-03-26 18:56:45 +08:00
|
|
|
EG(exception) = old_exception;
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_exception_error(EG(exception), E_ERROR);
|
2002-08-16 08:41:37 +08:00
|
|
|
}
|
|
|
|
} else {
|
2014-12-14 06:06:14 +08:00
|
|
|
zend_exception_error(EG(exception), E_ERROR);
|
2002-08-16 08:41:37 +08:00
|
|
|
}
|
2001-08-31 21:11:52 +08:00
|
|
|
}
|
2014-12-14 06:06:14 +08:00
|
|
|
destroy_op_array(op_array);
|
2014-08-28 00:49:56 +08:00
|
|
|
efree_size(op_array, sizeof(zend_op_array));
|
2000-08-10 03:22:35 +08:00
|
|
|
} else if (type==ZEND_REQUIRE) {
|
|
|
|
va_end(files);
|
|
|
|
return FAILURE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
va_end(files);
|
|
|
|
|
|
|
|
return SUCCESS;
|
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
2000-08-10 03:22:35 +08:00
|
|
|
|
2000-09-13 03:47:25 +08:00
|
|
|
#define COMPILED_STRING_DESCRIPTION_FORMAT "%s(%d) : %s"
|
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
ZEND_API char *zend_make_compiled_string_description(const char *name) /* {{{ */
|
2000-09-13 03:47:25 +08:00
|
|
|
{
|
2011-09-13 21:29:35 +08:00
|
|
|
const char *cur_filename;
|
2000-09-13 03:47:25 +08:00
|
|
|
int cur_lineno;
|
|
|
|
char *compiled_string_description;
|
|
|
|
|
2014-12-14 06:06:14 +08:00
|
|
|
if (zend_is_compiling()) {
|
2015-06-30 18:59:27 +08:00
|
|
|
cur_filename = ZSTR_VAL(zend_get_compiled_filename());
|
2014-12-14 06:06:14 +08:00
|
|
|
cur_lineno = zend_get_compiled_lineno();
|
|
|
|
} else if (zend_is_executing()) {
|
|
|
|
cur_filename = zend_get_executed_filename();
|
|
|
|
cur_lineno = zend_get_executed_lineno();
|
2000-09-13 03:47:25 +08:00
|
|
|
} else {
|
|
|
|
cur_filename = "Unknown";
|
|
|
|
cur_lineno = 0;
|
|
|
|
}
|
|
|
|
|
2007-02-24 10:17:47 +08:00
|
|
|
zend_spprintf(&compiled_string_description, 0, COMPILED_STRING_DESCRIPTION_FORMAT, cur_filename, cur_lineno, name);
|
2000-09-13 03:47:25 +08:00
|
|
|
return compiled_string_description;
|
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
2000-09-13 03:47:25 +08:00
|
|
|
|
2007-11-03 03:40:39 +08:00
|
|
|
void free_estring(char **str_p) /* {{{ */
|
2001-01-15 18:52:06 +08:00
|
|
|
{
|
|
|
|
efree(*str_p);
|
|
|
|
}
|
2014-09-20 13:51:58 +08:00
|
|
|
/* }}} */
|
2014-02-17 21:59:18 +08:00
|
|
|
|
|
|
|
void free_string_zval(zval *zv) /* {{{ */
|
|
|
|
{
|
|
|
|
zend_string *str = Z_PTR_P(zv);
|
2014-08-26 01:24:55 +08:00
|
|
|
zend_string_release(str);
|
2014-02-17 21:59:18 +08:00
|
|
|
}
|
2007-11-03 03:40:39 +08:00
|
|
|
/* }}} */
|
2003-02-11 00:11:24 +08:00
|
|
|
|
2002-08-16 18:12:17 +08:00
|
|
|
/*
|
|
|
|
* Local variables:
|
|
|
|
* tab-width: 4
|
|
|
|
* c-basic-offset: 4
|
|
|
|
* indent-tabs-mode: t
|
|
|
|
* End:
|
|
|
|
*/
|