root/Zend/zend.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ZEND_INI_MH
  2. ZEND_INI_MH
  3. ZEND_INI_MH
  4. ZEND_INI_MH
  5. print_hash
  6. print_flat_hash
  7. zend_make_printable_zval
  8. zend_print_zval
  9. zend_print_zval_ex
  10. zend_print_flat_zval_r
  11. zend_print_zval_r
  12. zend_print_zval_r_ex
  13. zend_fopen_wrapper
  14. zend_set_default_compile_time_values
  15. zend_get_windows_version_info
  16. zend_init_exception_op
  17. zend_init_call_trampoline_op
  18. auto_global_dtor
  19. function_copy_ctor
  20. auto_global_copy_ctor
  21. compiler_globals_ctor
  22. compiler_globals_dtor
  23. executor_globals_ctor
  24. executor_globals_dtor
  25. zend_new_thread_end_handler
  26. ini_scanner_globals_ctor
  27. php_scanner_globals_ctor
  28. module_destructor_zval
  29. php_auto_globals_create_globals
  30. zend_startup
  31. zend_register_standard_ini_entries
  32. zend_post_startup
  33. zend_shutdown
  34. zend_set_utility_values
  35. zenderror
  36. BEGIN_EXTERN_C
  37. END_EXTERN_C
  38. get_zend_version
  39. zend_activate
  40. zend_call_destructors
  41. zend_deactivate
  42. BEGIN_EXTERN_C
  43. END_EXTERN_C
  44. zend_error
  45. zend_error
  46. zend_error_noreturn
  47. zend_throw_error
  48. zend_type_error
  49. zend_internal_type_error
  50. zend_output_debug_string
  51. zend_try_exception_handler
  52. zend_execute_scripts
  53. zend_make_compiled_string_description
  54. free_estring

   1 /*
   2    +----------------------------------------------------------------------+
   3    | Zend Engine                                                          |
   4    +----------------------------------------------------------------------+
   5    | Copyright (c) 1998-2016 Zend Technologies Ltd. (http://www.zend.com) |
   6    +----------------------------------------------------------------------+
   7    | This source file is subject to version 2.00 of the Zend license,     |
   8    | that is bundled with this package in the file LICENSE, and is        |
   9    | available through the world-wide-web at the following url:           |
  10    | http://www.zend.com/license/2_00.txt.                                |
  11    | If you did not receive a copy of the Zend license and are unable to  |
  12    | obtain it through the world-wide-web, please send a note to          |
  13    | license@zend.com so we can mail you a copy immediately.              |
  14    +----------------------------------------------------------------------+
  15    | Authors: Andi Gutmans <andi@zend.com>                                |
  16    |          Zeev Suraski <zeev@zend.com>                                |
  17    +----------------------------------------------------------------------+
  18 */
  19 
  20 /* $Id$ */
  21 
  22 #include "zend.h"
  23 #include "zend_extensions.h"
  24 #include "zend_modules.h"
  25 #include "zend_constants.h"
  26 #include "zend_list.h"
  27 #include "zend_API.h"
  28 #include "zend_exceptions.h"
  29 #include "zend_builtin_functions.h"
  30 #include "zend_ini.h"
  31 #include "zend_vm.h"
  32 #include "zend_dtrace.h"
  33 #include "zend_virtual_cwd.h"
  34 
  35 #ifdef ZTS
  36 # define GLOBAL_FUNCTION_TABLE          global_function_table
  37 # define GLOBAL_CLASS_TABLE                     global_class_table
  38 # define GLOBAL_CONSTANTS_TABLE         global_constants_table
  39 # define GLOBAL_AUTO_GLOBALS_TABLE      global_auto_globals_table
  40 #else
  41 # define GLOBAL_FUNCTION_TABLE          CG(function_table)
  42 # define GLOBAL_CLASS_TABLE                     CG(class_table)
  43 # define GLOBAL_AUTO_GLOBALS_TABLE      CG(auto_globals)
  44 # define GLOBAL_CONSTANTS_TABLE         EG(zend_constants)
  45 #endif
  46 
  47 /* true multithread-shared globals */
  48 ZEND_API zend_class_entry *zend_standard_class_def = NULL;
  49 ZEND_API size_t (*zend_printf)(const char *format, ...);
  50 ZEND_API zend_write_func_t zend_write;
  51 ZEND_API FILE *(*zend_fopen)(const char *filename, zend_string **opened_path);
  52 ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle);
  53 ZEND_API void (*zend_block_interruptions)(void);
  54 ZEND_API void (*zend_unblock_interruptions)(void);
  55 ZEND_API void (*zend_ticks_function)(int ticks);
  56 ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
  57 size_t (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
  58 zend_string *(*zend_vstrpprintf)(size_t max_len, const char *format, va_list ap);
  59 ZEND_API char *(*zend_getenv)(char *name, size_t name_len);
  60 ZEND_API zend_string *(*zend_resolve_path)(const char *filename, int filename_len);
  61 
  62 void (*zend_on_timeout)(int seconds);
  63 
  64 static void (*zend_message_dispatcher_p)(zend_long message, const void *data);
  65 static zval *(*zend_get_configuration_directive_p)(zend_string *name);
  66 
  67 static ZEND_INI_MH(OnUpdateErrorReporting) /* {{{ */
  68 {
  69         if (!new_value) {
  70                 EG(error_reporting) = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED;
  71         } else {
  72                 EG(error_reporting) = atoi(ZSTR_VAL(new_value));
  73         }
  74         return SUCCESS;
  75 }
  76 /* }}} */
  77 
  78 static ZEND_INI_MH(OnUpdateGCEnabled) /* {{{ */
  79 {
  80         OnUpdateBool(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
  81 
  82         if (GC_G(gc_enabled)) {
  83                 gc_init();
  84         }
  85 
  86         return SUCCESS;
  87 }
  88 /* }}} */
  89 
  90 static ZEND_INI_MH(OnUpdateScriptEncoding) /* {{{ */
  91 {
  92         if (!CG(multibyte)) {
  93                 return FAILURE;
  94         }
  95         if (!zend_multibyte_get_functions()) {
  96                 return SUCCESS;
  97         }
  98         return zend_multibyte_set_script_encoding_by_string(new_value ? ZSTR_VAL(new_value) : NULL, new_value ? ZSTR_LEN(new_value) : 0);
  99 }
 100 /* }}} */
 101 
 102 static ZEND_INI_MH(OnUpdateAssertions) /* {{{ */
 103 {
 104         zend_long *p, val;
 105 #ifndef ZTS
 106         char *base = (char *) mh_arg2;
 107 #else
 108         char *base;
 109 
 110         base = (char *) ts_resource(*((int *) mh_arg2));
 111 #endif
 112 
 113         p = (zend_long *) (base+(size_t) mh_arg1);
 114 
 115         val = zend_atol(ZSTR_VAL(new_value), (int)ZSTR_LEN(new_value));
 116 
 117         if (stage != ZEND_INI_STAGE_STARTUP &&
 118             stage != ZEND_INI_STAGE_SHUTDOWN &&
 119             *p != val &&
 120             (*p < 0 || val < 0)) {
 121                 zend_error(E_WARNING, "zend.assertions may be completely enabled or disabled only in php.ini");
 122                 return FAILURE;
 123         }
 124 
 125         *p = val;
 126         return SUCCESS;
 127 }
 128 /* }}} */
 129 
 130 ZEND_INI_BEGIN()
 131         ZEND_INI_ENTRY("error_reporting",                               NULL,           ZEND_INI_ALL,           OnUpdateErrorReporting)
 132         STD_ZEND_INI_ENTRY("zend.assertions",                           "1",    ZEND_INI_ALL,       OnUpdateAssertions,           assertions,   zend_executor_globals,  executor_globals)
 133         STD_ZEND_INI_BOOLEAN("zend.enable_gc",                          "1",    ZEND_INI_ALL,           OnUpdateGCEnabled,      gc_enabled,     zend_gc_globals,        gc_globals)
 134         STD_ZEND_INI_BOOLEAN("zend.multibyte", "0", ZEND_INI_PERDIR, OnUpdateBool, multibyte,      zend_compiler_globals, compiler_globals)
 135         ZEND_INI_ENTRY("zend.script_encoding",                  NULL,           ZEND_INI_ALL,           OnUpdateScriptEncoding)
 136         STD_ZEND_INI_BOOLEAN("zend.detect_unicode",                     "1",    ZEND_INI_ALL,           OnUpdateBool, detect_unicode, zend_compiler_globals, compiler_globals)
 137 #ifdef ZEND_SIGNALS
 138         STD_ZEND_INI_BOOLEAN("zend.signal_check", "0", ZEND_INI_SYSTEM, OnUpdateBool, check, zend_signal_globals_t, zend_signal_globals)
 139 #endif
 140 ZEND_INI_END()
 141 
 142 
 143 #ifdef ZTS
 144 ZEND_API int compiler_globals_id;
 145 ZEND_API int executor_globals_id;
 146 static HashTable *global_function_table = NULL;
 147 static HashTable *global_class_table = NULL;
 148 static HashTable *global_constants_table = NULL;
 149 static HashTable *global_auto_globals_table = NULL;
 150 static HashTable *global_persistent_list = NULL;
 151 ZEND_TSRMLS_CACHE_DEFINE()
 152 #endif
 153 
 154 ZEND_API zend_utility_values zend_uv;
 155 
 156 /* version information */
 157 static char *zend_version_info;
 158 static uint zend_version_info_length;
 159 #define ZEND_CORE_VERSION_INFO  "Zend Engine v" ZEND_VERSION ", Copyright (c) 1998-2016 Zend Technologies\n"
 160 #define PRINT_ZVAL_INDENT 4
 161 
 162 static void print_hash(zend_write_func_t write_func, HashTable *ht, int indent, zend_bool is_object) /* {{{ */
 163 {
 164         zval *tmp;
 165         zend_string *string_key;
 166         zend_ulong num_key;
 167         int i;
 168 
 169         for (i = 0; i < indent; i++) {
 170                 ZEND_PUTS_EX(" ");
 171         }
 172         ZEND_PUTS_EX("(\n");
 173         indent += PRINT_ZVAL_INDENT;
 174         ZEND_HASH_FOREACH_KEY_VAL(ht, num_key, string_key, tmp) {
 175                 if (Z_TYPE_P(tmp) == IS_INDIRECT) {
 176                         tmp = Z_INDIRECT_P(tmp);
 177                         if (Z_TYPE_P(tmp) == IS_UNDEF) {
 178                                 continue;
 179                         }
 180                 }
 181                 for (i = 0; i < indent; i++) {
 182                         ZEND_PUTS_EX(" ");
 183                 }
 184                 ZEND_PUTS_EX("[");
 185                 if (string_key) {
 186                         if (is_object) {
 187                                 const char *prop_name, *class_name;
 188                                 size_t prop_len;
 189                                 int mangled = zend_unmangle_property_name_ex(string_key, &class_name, &prop_name, &prop_len);
 190 
 191                                 ZEND_WRITE_EX(prop_name, prop_len);
 192                                 if (class_name && mangled == SUCCESS) {
 193                                         if (class_name[0]=='*') {
 194                                                 ZEND_PUTS_EX(":protected");
 195                                         } else {
 196                                                 ZEND_PUTS_EX(":");
 197                                                 ZEND_PUTS_EX(class_name);
 198                                                 ZEND_PUTS_EX(":private");
 199                                         }
 200                                 }
 201                         } else {
 202                                 ZEND_WRITE_EX(ZSTR_VAL(string_key), ZSTR_LEN(string_key));
 203                         }
 204                 } else {
 205                         char key[25];
 206                         snprintf(key, sizeof(key), ZEND_LONG_FMT, num_key);
 207                         ZEND_PUTS_EX(key);
 208                 }
 209                 ZEND_PUTS_EX("] => ");
 210                 zend_print_zval_r_ex(write_func, tmp, indent+PRINT_ZVAL_INDENT);
 211                 ZEND_PUTS_EX("\n");
 212         } ZEND_HASH_FOREACH_END();
 213         indent -= PRINT_ZVAL_INDENT;
 214         for (i = 0; i < indent; i++) {
 215                 ZEND_PUTS_EX(" ");
 216         }
 217         ZEND_PUTS_EX(")\n");
 218 }
 219 /* }}} */
 220 
 221 static void print_flat_hash(HashTable *ht) /* {{{ */
 222 {
 223         zval *tmp;
 224         zend_string *string_key;
 225         zend_ulong num_key;
 226         int i = 0;
 227 
 228         ZEND_HASH_FOREACH_KEY_VAL_IND(ht, num_key, string_key, tmp) {
 229                 if (i++ > 0) {
 230                         ZEND_PUTS(",");
 231                 }
 232                 ZEND_PUTS("[");
 233                 if (string_key) {
 234                         ZEND_WRITE(ZSTR_VAL(string_key), ZSTR_LEN(string_key));
 235                 } else {
 236                         zend_printf(ZEND_ULONG_FMT, num_key);
 237                 }
 238                 ZEND_PUTS("] => ");
 239                 zend_print_flat_zval_r(tmp);
 240         } ZEND_HASH_FOREACH_END();
 241 }
 242 /* }}} */
 243 
 244 ZEND_API int zend_make_printable_zval(zval *expr, zval *expr_copy) /* {{{ */
 245 {
 246         if (Z_TYPE_P(expr) == IS_STRING) {
 247                 return 0;
 248         } else {
 249                 ZVAL_STR(expr_copy, _zval_get_string_func(expr));
 250                 return 1;
 251         }
 252 }
 253 /* }}} */
 254 
 255 ZEND_API size_t zend_print_zval(zval *expr, int indent) /* {{{ */
 256 {
 257         return zend_print_zval_ex(zend_write, expr, indent);
 258 }
 259 /* }}} */
 260 
 261 ZEND_API size_t zend_print_zval_ex(zend_write_func_t write_func, zval *expr, int indent) /* {{{ */
 262 {
 263         zend_string *str = zval_get_string(expr);
 264         size_t len = ZSTR_LEN(str);
 265 
 266         if (len != 0) {
 267                 write_func(ZSTR_VAL(str), len);
 268         }
 269 
 270         zend_string_release(str);
 271         return len;
 272 }
 273 /* }}} */
 274 
 275 ZEND_API void zend_print_flat_zval_r(zval *expr) /* {{{ */
 276 {
 277         switch (Z_TYPE_P(expr)) {
 278                 case IS_ARRAY:
 279                         ZEND_PUTS("Array (");
 280                         if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(expr)) &&
 281                             ++Z_ARRVAL_P(expr)->u.v.nApplyCount>1) {
 282                                 ZEND_PUTS(" *RECURSION*");
 283                                 Z_ARRVAL_P(expr)->u.v.nApplyCount--;
 284                                 return;
 285                         }
 286                         print_flat_hash(Z_ARRVAL_P(expr));
 287                         ZEND_PUTS(")");
 288                         if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(expr))) {
 289                                 Z_ARRVAL_P(expr)->u.v.nApplyCount--;
 290                         }
 291                         break;
 292                 case IS_OBJECT:
 293                 {
 294                         HashTable *properties = NULL;
 295                         zend_string *class_name = Z_OBJ_HANDLER_P(expr, get_class_name)(Z_OBJ_P(expr));
 296                         zend_printf("%s Object (", ZSTR_VAL(class_name));
 297                         zend_string_release(class_name);
 298 
 299                         if (Z_OBJ_APPLY_COUNT_P(expr) > 0) {
 300                                 ZEND_PUTS(" *RECURSION*");
 301                                 return;
 302                         }
 303 
 304                         if (Z_OBJ_HANDLER_P(expr, get_properties)) {
 305                                 properties = Z_OBJPROP_P(expr);
 306                         }
 307                         if (properties) {
 308                                 Z_OBJ_INC_APPLY_COUNT_P(expr);
 309                                 print_flat_hash(properties);
 310                                 Z_OBJ_DEC_APPLY_COUNT_P(expr);
 311                         }
 312                         ZEND_PUTS(")");
 313                         break;
 314                 }
 315                 default:
 316                         zend_print_variable(expr);
 317                         break;
 318         }
 319 }
 320 /* }}} */
 321 
 322 ZEND_API void zend_print_zval_r(zval *expr, int indent) /* {{{ */
 323 {
 324         zend_print_zval_r_ex(zend_write, expr, indent);
 325 }
 326 /* }}} */
 327 
 328 ZEND_API void zend_print_zval_r_ex(zend_write_func_t write_func, zval *expr, int indent) /* {{{ */
 329 {
 330         ZVAL_DEREF(expr);
 331         switch (Z_TYPE_P(expr)) {
 332                 case IS_ARRAY:
 333                         ZEND_PUTS_EX("Array\n");
 334                         if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(expr)) &&
 335                             ++Z_ARRVAL_P(expr)->u.v.nApplyCount>1) {
 336                                 ZEND_PUTS_EX(" *RECURSION*");
 337                                 Z_ARRVAL_P(expr)->u.v.nApplyCount--;
 338                                 return;
 339                         }
 340                         print_hash(write_func, Z_ARRVAL_P(expr), indent, 0);
 341                         if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(expr))) {
 342                                 Z_ARRVAL_P(expr)->u.v.nApplyCount--;
 343                         }
 344                         break;
 345                 case IS_OBJECT:
 346                         {
 347                                 HashTable *properties;
 348                                 int is_temp;
 349 
 350                                 zend_string *class_name = Z_OBJ_HANDLER_P(expr, get_class_name)(Z_OBJ_P(expr));
 351                                 ZEND_PUTS_EX(ZSTR_VAL(class_name));
 352                                 zend_string_release(class_name);
 353 
 354                                 ZEND_PUTS_EX(" Object\n");
 355                                 if (Z_OBJ_APPLY_COUNT_P(expr) > 0) {
 356                                         ZEND_PUTS_EX(" *RECURSION*");
 357                                         return;
 358                                 }
 359                                 if ((properties = Z_OBJDEBUG_P(expr, is_temp)) == NULL) {
 360                                         break;
 361                                 }
 362 
 363                                 Z_OBJ_INC_APPLY_COUNT_P(expr);
 364                                 print_hash(write_func, properties, indent, 1);
 365                                 Z_OBJ_DEC_APPLY_COUNT_P(expr);
 366 
 367                                 if (is_temp) {
 368                                         zend_hash_destroy(properties);
 369                                         FREE_HASHTABLE(properties);
 370                                 }
 371                                 break;
 372                         }
 373                 default:
 374                         zend_print_zval_ex(write_func, expr, indent);
 375                         break;
 376         }
 377 }
 378 /* }}} */
 379 
 380 static FILE *zend_fopen_wrapper(const char *filename, zend_string **opened_path) /* {{{ */
 381 {
 382         if (opened_path) {
 383                 *opened_path = zend_string_init(filename, strlen(filename), 0);
 384         }
 385         return fopen(filename, "rb");
 386 }
 387 /* }}} */
 388 
 389 #ifdef ZTS
 390 static zend_bool short_tags_default      = 1;
 391 static uint32_t compiler_options_default = ZEND_COMPILE_DEFAULT;
 392 #else
 393 # define short_tags_default                     1
 394 # define compiler_options_default       ZEND_COMPILE_DEFAULT
 395 #endif
 396 
 397 static void zend_set_default_compile_time_values(void) /* {{{ */
 398 {
 399         /* default compile-time values */
 400         CG(short_tags) = short_tags_default;
 401         CG(compiler_options) = compiler_options_default;
 402 }
 403 /* }}} */
 404 
 405 #ifdef ZEND_WIN32
 406 static void zend_get_windows_version_info(OSVERSIONINFOEX *osvi) /* {{{ */
 407 {
 408         ZeroMemory(osvi, sizeof(OSVERSIONINFOEX));
 409         osvi->dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
 410         if(!GetVersionEx((OSVERSIONINFO *) osvi)) {
 411                 ZEND_ASSERT(0); /* Should not happen as sizeof is used. */
 412         }
 413 }
 414 /* }}} */
 415 #endif
 416 
 417 static void zend_init_exception_op(void) /* {{{ */
 418 {
 419         memset(EG(exception_op), 0, sizeof(EG(exception_op)));
 420         EG(exception_op)[0].opcode = ZEND_HANDLE_EXCEPTION;
 421         EG(exception_op)[0].op1_type = IS_UNUSED;
 422         EG(exception_op)[0].op2_type = IS_UNUSED;
 423         EG(exception_op)[0].result_type = IS_UNUSED;
 424         ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op));
 425         EG(exception_op)[1].opcode = ZEND_HANDLE_EXCEPTION;
 426         EG(exception_op)[1].op1_type = IS_UNUSED;
 427         EG(exception_op)[1].op2_type = IS_UNUSED;
 428         EG(exception_op)[1].result_type = IS_UNUSED;
 429         ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op)+1);
 430         EG(exception_op)[2].opcode = ZEND_HANDLE_EXCEPTION;
 431         EG(exception_op)[2].op1_type = IS_UNUSED;
 432         EG(exception_op)[2].op2_type = IS_UNUSED;
 433         EG(exception_op)[2].result_type = IS_UNUSED;
 434         ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op)+2);
 435 }
 436 /* }}} */
 437 
 438 static void zend_init_call_trampoline_op(void) /* {{{ */
 439 {
 440         memset(&EG(call_trampoline_op), 0, sizeof(EG(call_trampoline_op)));
 441         EG(call_trampoline_op).opcode = ZEND_CALL_TRAMPOLINE;
 442         EG(call_trampoline_op).op1_type = IS_UNUSED;
 443         EG(call_trampoline_op).op2_type = IS_UNUSED;
 444         EG(call_trampoline_op).result_type = IS_UNUSED;
 445         ZEND_VM_SET_OPCODE_HANDLER(&EG(call_trampoline_op));
 446 }
 447 /* }}} */
 448 
 449 static void auto_global_dtor(zval *zv) /* {{{ */
 450 {
 451         free(Z_PTR_P(zv));
 452 }
 453 /* }}} */
 454 
 455 #ifdef ZTS
 456 static void function_copy_ctor(zval *zv) /* {{{ */
 457 {
 458         zend_function *old_func = Z_FUNC_P(zv);
 459         Z_FUNC_P(zv) = pemalloc(sizeof(zend_internal_function), 1);
 460         memcpy(Z_FUNC_P(zv), old_func, sizeof(zend_internal_function));
 461         function_add_ref(Z_FUNC_P(zv));
 462 }
 463 /* }}} */
 464 
 465 static void auto_global_copy_ctor(zval *zv) /* {{{ */
 466 {
 467         zend_auto_global *old_ag = (zend_auto_global *) Z_PTR_P(zv);
 468         zend_auto_global *new_ag = pemalloc(sizeof(zend_auto_global), 1);
 469 
 470         new_ag->name = old_ag->name;
 471         new_ag->auto_global_callback = old_ag->auto_global_callback;
 472         new_ag->jit = old_ag->jit;
 473 
 474         Z_PTR_P(zv) = new_ag;
 475 }
 476 /* }}} */
 477 
 478 static void compiler_globals_ctor(zend_compiler_globals *compiler_globals) /* {{{ */
 479 {
 480         compiler_globals->compiled_filename = NULL;
 481 
 482         compiler_globals->function_table = (HashTable *) malloc(sizeof(HashTable));
 483         zend_hash_init_ex(compiler_globals->function_table, 1024, NULL, ZEND_FUNCTION_DTOR, 1, 0);
 484         zend_hash_copy(compiler_globals->function_table, global_function_table, function_copy_ctor);
 485 
 486         compiler_globals->class_table = (HashTable *) malloc(sizeof(HashTable));
 487         zend_hash_init_ex(compiler_globals->class_table, 64, NULL, ZEND_CLASS_DTOR, 1, 0);
 488         zend_hash_copy(compiler_globals->class_table, global_class_table, zend_class_add_ref);
 489 
 490         zend_set_default_compile_time_values();
 491 
 492         compiler_globals->auto_globals = (HashTable *) malloc(sizeof(HashTable));
 493         zend_hash_init_ex(compiler_globals->auto_globals, 8, NULL, auto_global_dtor, 1, 0);
 494         zend_hash_copy(compiler_globals->auto_globals, global_auto_globals_table, auto_global_copy_ctor);
 495 
 496         compiler_globals->last_static_member = zend_hash_num_elements(compiler_globals->class_table);
 497         if (compiler_globals->last_static_member) {
 498                 compiler_globals->static_members_table = calloc(compiler_globals->last_static_member, sizeof(zval*));
 499         } else {
 500                 compiler_globals->static_members_table = NULL;
 501         }
 502         compiler_globals->script_encoding_list = NULL;
 503 
 504         zend_interned_empty_string_init(&compiler_globals->empty_string);
 505 
 506         memset(compiler_globals->one_char_string, 0, sizeof(compiler_globals->one_char_string));
 507 }
 508 /* }}} */
 509 
 510 static void compiler_globals_dtor(zend_compiler_globals *compiler_globals) /* {{{ */
 511 {
 512         if (compiler_globals->function_table != GLOBAL_FUNCTION_TABLE) {
 513                 zend_hash_destroy(compiler_globals->function_table);
 514                 free(compiler_globals->function_table);
 515         }
 516         if (compiler_globals->class_table != GLOBAL_CLASS_TABLE) {
 517                 zend_hash_destroy(compiler_globals->class_table);
 518                 free(compiler_globals->class_table);
 519         }
 520         if (compiler_globals->auto_globals != GLOBAL_AUTO_GLOBALS_TABLE) {
 521                 zend_hash_destroy(compiler_globals->auto_globals);
 522                 free(compiler_globals->auto_globals);
 523         }
 524         if (compiler_globals->static_members_table) {
 525                 free(compiler_globals->static_members_table);
 526         }
 527         if (compiler_globals->script_encoding_list) {
 528                 pefree((char*)compiler_globals->script_encoding_list, 1);
 529         }
 530         compiler_globals->last_static_member = 0;
 531 
 532         zend_interned_empty_string_free(&compiler_globals->empty_string);
 533 }
 534 /* }}} */
 535 
 536 static void executor_globals_ctor(zend_executor_globals *executor_globals) /* {{{ */
 537 {
 538         ZEND_TSRMLS_CACHE_UPDATE();
 539 
 540         zend_startup_constants();
 541         zend_copy_constants(EG(zend_constants), GLOBAL_CONSTANTS_TABLE);
 542         zend_init_rsrc_plist();
 543         zend_init_exception_op();
 544         zend_init_call_trampoline_op();
 545         memset(&executor_globals->trampoline, 0, sizeof(zend_op_array));
 546         executor_globals->lambda_count = 0;
 547         ZVAL_UNDEF(&executor_globals->user_error_handler);
 548         ZVAL_UNDEF(&executor_globals->user_exception_handler);
 549         executor_globals->in_autoload = NULL;
 550         executor_globals->current_execute_data = NULL;
 551         executor_globals->current_module = NULL;
 552         executor_globals->exit_status = 0;
 553 #if XPFPA_HAVE_CW
 554         executor_globals->saved_fpu_cw = 0;
 555 #endif
 556         executor_globals->saved_fpu_cw_ptr = NULL;
 557         executor_globals->active = 0;
 558         executor_globals->bailout = NULL;
 559         executor_globals->error_handling  = EH_NORMAL;
 560         executor_globals->exception_class = NULL;
 561         executor_globals->exception = NULL;
 562         executor_globals->objects_store.object_buckets = NULL;
 563 #ifdef ZEND_WIN32
 564         zend_get_windows_version_info(&executor_globals->windows_version_info);
 565 #endif
 566 }
 567 /* }}} */
 568 
 569 static void executor_globals_dtor(zend_executor_globals *executor_globals) /* {{{ */
 570 {
 571         zend_ini_dtor(executor_globals->ini_directives);
 572 
 573         if (&executor_globals->persistent_list != global_persistent_list) {
 574                 zend_destroy_rsrc_list(&executor_globals->persistent_list);
 575         }
 576         if (executor_globals->zend_constants != GLOBAL_CONSTANTS_TABLE) {
 577                 zend_hash_destroy(executor_globals->zend_constants);
 578                 free(executor_globals->zend_constants);
 579         }
 580 }
 581 /* }}} */
 582 
 583 static void zend_new_thread_end_handler(THREAD_T thread_id) /* {{{ */
 584 {
 585         if (zend_copy_ini_directives() == SUCCESS) {
 586                 zend_ini_refresh_caches(ZEND_INI_STAGE_STARTUP);
 587         }
 588 }
 589 /* }}} */
 590 #endif
 591 
 592 #if defined(__FreeBSD__) || defined(__DragonFly__)
 593 /* FreeBSD and DragonFly floating point precision fix */
 594 #include <floatingpoint.h>
 595 #endif
 596 
 597 static void ini_scanner_globals_ctor(zend_ini_scanner_globals *scanner_globals_p) /* {{{ */
 598 {
 599         memset(scanner_globals_p, 0, sizeof(*scanner_globals_p));
 600 }
 601 /* }}} */
 602 
 603 static void php_scanner_globals_ctor(zend_php_scanner_globals *scanner_globals_p) /* {{{ */
 604 {
 605         memset(scanner_globals_p, 0, sizeof(*scanner_globals_p));
 606 }
 607 /* }}} */
 608 
 609 void zend_init_opcodes_handlers(void);
 610 
 611 static void module_destructor_zval(zval *zv) /* {{{ */
 612 {
 613         zend_module_entry *module = (zend_module_entry*)Z_PTR_P(zv);
 614 
 615         module_destructor(module);
 616         free(module);
 617 }
 618 /* }}} */
 619 
 620 static zend_bool php_auto_globals_create_globals(zend_string *name) /* {{{ */
 621 {
 622         zval globals;
 623 
 624         ZVAL_ARR(&globals, &EG(symbol_table));
 625         Z_TYPE_INFO_P(&globals) = IS_ARRAY | (IS_TYPE_SYMBOLTABLE << Z_TYPE_FLAGS_SHIFT);
 626         ZVAL_NEW_REF(&globals, &globals);
 627         zend_hash_update(&EG(symbol_table), name, &globals);
 628         return 0;
 629 }
 630 /* }}} */
 631 
 632 int zend_startup(zend_utility_functions *utility_functions, char **extensions) /* {{{ */
 633 {
 634 #ifdef ZTS
 635         zend_compiler_globals *compiler_globals;
 636         zend_executor_globals *executor_globals;
 637         extern ZEND_API ts_rsrc_id ini_scanner_globals_id;
 638         extern ZEND_API ts_rsrc_id language_scanner_globals_id;
 639         ZEND_TSRMLS_CACHE_UPDATE();
 640 #else
 641         extern zend_ini_scanner_globals ini_scanner_globals;
 642         extern zend_php_scanner_globals language_scanner_globals;
 643 #endif
 644 
 645         start_memory_manager();
 646 
 647         virtual_cwd_startup(); /* Could use shutdown to free the main cwd but it would just slow it down for CGI */
 648 
 649 #if defined(__FreeBSD__) || defined(__DragonFly__)
 650         /* FreeBSD and DragonFly floating point precision fix */
 651         fpsetmask(0);
 652 #endif
 653 
 654         zend_startup_strtod();
 655         zend_startup_extensions_mechanism();
 656 
 657         /* Set up utility functions and values */
 658         zend_error_cb = utility_functions->error_function;
 659         zend_printf = utility_functions->printf_function;
 660         zend_write = (zend_write_func_t) utility_functions->write_function;
 661         zend_fopen = utility_functions->fopen_function;
 662         if (!zend_fopen) {
 663                 zend_fopen = zend_fopen_wrapper;
 664         }
 665         zend_stream_open_function = utility_functions->stream_open_function;
 666         zend_message_dispatcher_p = utility_functions->message_handler;
 667 #ifndef ZEND_SIGNALS
 668         zend_block_interruptions = utility_functions->block_interruptions;
 669         zend_unblock_interruptions = utility_functions->unblock_interruptions;
 670 #endif
 671         zend_get_configuration_directive_p = utility_functions->get_configuration_directive;
 672         zend_ticks_function = utility_functions->ticks_function;
 673         zend_on_timeout = utility_functions->on_timeout;
 674         zend_vspprintf = utility_functions->vspprintf_function;
 675         zend_vstrpprintf = utility_functions->vstrpprintf_function;
 676         zend_getenv = utility_functions->getenv_function;
 677         zend_resolve_path = utility_functions->resolve_path_function;
 678 
 679 #if HAVE_DTRACE
 680 /* build with dtrace support */
 681         zend_compile_file = dtrace_compile_file;
 682         zend_execute_ex = dtrace_execute_ex;
 683         zend_execute_internal = dtrace_execute_internal;
 684 #else
 685         zend_compile_file = compile_file;
 686         zend_execute_ex = execute_ex;
 687         zend_execute_internal = NULL;
 688 #endif /* HAVE_SYS_SDT_H */
 689         zend_compile_string = compile_string;
 690         zend_throw_exception_hook = NULL;
 691 
 692         /* Set up the default garbage collection implementation. */
 693         gc_collect_cycles = zend_gc_collect_cycles;
 694 
 695         zend_init_opcodes_handlers();
 696 
 697         /* set up version */
 698         zend_version_info = strdup(ZEND_CORE_VERSION_INFO);
 699         zend_version_info_length = sizeof(ZEND_CORE_VERSION_INFO) - 1;
 700 
 701         GLOBAL_FUNCTION_TABLE = (HashTable *) malloc(sizeof(HashTable));
 702         GLOBAL_CLASS_TABLE = (HashTable *) malloc(sizeof(HashTable));
 703         GLOBAL_AUTO_GLOBALS_TABLE = (HashTable *) malloc(sizeof(HashTable));
 704         GLOBAL_CONSTANTS_TABLE = (HashTable *) malloc(sizeof(HashTable));
 705 
 706         zend_hash_init_ex(GLOBAL_FUNCTION_TABLE, 1024, NULL, ZEND_FUNCTION_DTOR, 1, 0);
 707         zend_hash_init_ex(GLOBAL_CLASS_TABLE, 64, NULL, ZEND_CLASS_DTOR, 1, 0);
 708         zend_hash_init_ex(GLOBAL_AUTO_GLOBALS_TABLE, 8, NULL, auto_global_dtor, 1, 0);
 709         zend_hash_init_ex(GLOBAL_CONSTANTS_TABLE, 128, NULL, ZEND_CONSTANT_DTOR, 1, 0);
 710 
 711         zend_hash_init_ex(&module_registry, 32, NULL, module_destructor_zval, 1, 0);
 712         zend_init_rsrc_list_dtors();
 713 
 714 #ifdef ZTS
 715         ts_allocate_id(&compiler_globals_id, sizeof(zend_compiler_globals), (ts_allocate_ctor) compiler_globals_ctor, (ts_allocate_dtor) compiler_globals_dtor);
 716         ts_allocate_id(&executor_globals_id, sizeof(zend_executor_globals), (ts_allocate_ctor) executor_globals_ctor, (ts_allocate_dtor) executor_globals_dtor);
 717         ts_allocate_id(&language_scanner_globals_id, sizeof(zend_php_scanner_globals), (ts_allocate_ctor) php_scanner_globals_ctor, NULL);
 718         ts_allocate_id(&ini_scanner_globals_id, sizeof(zend_ini_scanner_globals), (ts_allocate_ctor) ini_scanner_globals_ctor, NULL);
 719         compiler_globals = ts_resource(compiler_globals_id);
 720         executor_globals = ts_resource(executor_globals_id);
 721 
 722         compiler_globals_dtor(compiler_globals);
 723         compiler_globals->in_compilation = 0;
 724         compiler_globals->function_table = (HashTable *) malloc(sizeof(HashTable));
 725         compiler_globals->class_table = (HashTable *) malloc(sizeof(HashTable));
 726 
 727         *compiler_globals->function_table = *GLOBAL_FUNCTION_TABLE;
 728         *compiler_globals->class_table = *GLOBAL_CLASS_TABLE;
 729         compiler_globals->auto_globals = GLOBAL_AUTO_GLOBALS_TABLE;
 730 
 731         zend_hash_destroy(executor_globals->zend_constants);
 732         *executor_globals->zend_constants = *GLOBAL_CONSTANTS_TABLE;
 733 #else
 734         ini_scanner_globals_ctor(&ini_scanner_globals);
 735         php_scanner_globals_ctor(&language_scanner_globals);
 736         zend_set_default_compile_time_values();
 737 #ifdef ZEND_WIN32
 738         zend_get_windows_version_info(&EG(windows_version_info));
 739 #endif
 740 #endif
 741         EG(error_reporting) = E_ALL & ~E_NOTICE;
 742 
 743         zend_interned_strings_init();
 744         zend_startup_builtin_functions();
 745         zend_register_standard_constants();
 746         zend_register_auto_global(zend_string_init("GLOBALS", sizeof("GLOBALS") - 1, 1), 1, php_auto_globals_create_globals);
 747 
 748 #ifndef ZTS
 749         zend_init_rsrc_plist();
 750         zend_init_exception_op();
 751         zend_init_call_trampoline_op();
 752 #endif
 753 
 754         zend_ini_startup();
 755 
 756 #ifdef ZTS
 757         tsrm_set_new_thread_end_handler(zend_new_thread_end_handler);
 758 #endif
 759 
 760         return SUCCESS;
 761 }
 762 /* }}} */
 763 
 764 void zend_register_standard_ini_entries(void) /* {{{ */
 765 {
 766         int module_number = 0;
 767 
 768         REGISTER_INI_ENTRIES();
 769 }
 770 /* }}} */
 771 
 772 /* Unlink the global (r/o) copies of the class, function and constant tables,
 773  * and use a fresh r/w copy for the startup thread
 774  */
 775 void zend_post_startup(void) /* {{{ */
 776 {
 777 #ifdef ZTS
 778         zend_encoding **script_encoding_list;
 779 
 780         zend_compiler_globals *compiler_globals = ts_resource(compiler_globals_id);
 781         zend_executor_globals *executor_globals = ts_resource(executor_globals_id);
 782 
 783         *GLOBAL_FUNCTION_TABLE = *compiler_globals->function_table;
 784         *GLOBAL_CLASS_TABLE = *compiler_globals->class_table;
 785         *GLOBAL_CONSTANTS_TABLE = *executor_globals->zend_constants;
 786 
 787         short_tags_default = CG(short_tags);
 788         compiler_options_default = CG(compiler_options);
 789 
 790         zend_destroy_rsrc_list(&EG(persistent_list));
 791         free(compiler_globals->function_table);
 792         free(compiler_globals->class_table);
 793         if ((script_encoding_list = (zend_encoding **)compiler_globals->script_encoding_list)) {
 794                 compiler_globals_ctor(compiler_globals);
 795                 compiler_globals->script_encoding_list = (const zend_encoding **)script_encoding_list;
 796         } else {
 797                 compiler_globals_ctor(compiler_globals);
 798         }
 799         free(EG(zend_constants));
 800 
 801         virtual_cwd_deactivate();
 802 
 803         executor_globals_ctor(executor_globals);
 804         global_persistent_list = &EG(persistent_list);
 805         zend_copy_ini_directives();
 806 #else
 807         virtual_cwd_deactivate();
 808 #endif
 809 }
 810 /* }}} */
 811 
 812 void zend_shutdown(void) /* {{{ */
 813 {
 814         zend_destroy_rsrc_list(&EG(persistent_list));
 815         if (EG(active))
 816         {
 817                 /*
 818                  * The order of destruction is important here.
 819                  * See bugs #65463 and 66036.
 820                  */
 821                 zend_function *func;
 822                 zend_class_entry *ce;
 823 
 824                 ZEND_HASH_REVERSE_FOREACH_PTR(GLOBAL_FUNCTION_TABLE, func) {
 825                         if (func->type == ZEND_USER_FUNCTION) {
 826                                 zend_cleanup_op_array_data((zend_op_array *) func);
 827                         }
 828                 } ZEND_HASH_FOREACH_END();
 829                 ZEND_HASH_REVERSE_FOREACH_PTR(GLOBAL_CLASS_TABLE, ce) {
 830                         if (ce->type == ZEND_USER_CLASS) {
 831                                 zend_cleanup_user_class_data(ce);
 832                         } else {
 833                                 break;
 834                         }
 835                 } ZEND_HASH_FOREACH_END();
 836                 zend_cleanup_internal_classes();
 837                 zend_hash_reverse_apply(GLOBAL_FUNCTION_TABLE, (apply_func_t) clean_non_persistent_function_full);
 838                 zend_hash_reverse_apply(GLOBAL_CLASS_TABLE, (apply_func_t) clean_non_persistent_class_full);
 839         }
 840         zend_destroy_modules();
 841 
 842         virtual_cwd_deactivate();
 843         virtual_cwd_shutdown();
 844 
 845         zend_hash_destroy(GLOBAL_FUNCTION_TABLE);
 846         zend_hash_destroy(GLOBAL_CLASS_TABLE);
 847 
 848         zend_hash_destroy(GLOBAL_AUTO_GLOBALS_TABLE);
 849         free(GLOBAL_AUTO_GLOBALS_TABLE);
 850 
 851         zend_shutdown_extensions();
 852         free(zend_version_info);
 853 
 854         free(GLOBAL_FUNCTION_TABLE);
 855         free(GLOBAL_CLASS_TABLE);
 856 
 857         zend_hash_destroy(GLOBAL_CONSTANTS_TABLE);
 858         free(GLOBAL_CONSTANTS_TABLE);
 859         zend_shutdown_strtod();
 860 
 861 #ifdef ZTS
 862         GLOBAL_FUNCTION_TABLE = NULL;
 863         GLOBAL_CLASS_TABLE = NULL;
 864         GLOBAL_AUTO_GLOBALS_TABLE = NULL;
 865         GLOBAL_CONSTANTS_TABLE = NULL;
 866 #endif
 867         zend_destroy_rsrc_list_dtors();
 868 
 869         zend_interned_strings_dtor();
 870 }
 871 /* }}} */
 872 
 873 void zend_set_utility_values(zend_utility_values *utility_values) /* {{{ */
 874 {
 875         zend_uv = *utility_values;
 876         zend_uv.import_use_extension_length = (uint)strlen(zend_uv.import_use_extension);
 877 }
 878 /* }}} */
 879 
 880 /* this should be compatible with the standard zenderror */
 881 ZEND_COLD void zenderror(const char *error) /* {{{ */
 882 {
 883         if (EG(exception)) {
 884                 /* An exception was thrown in the lexer, don't throw another in the parser. */
 885                 return;
 886         }
 887 
 888         zend_throw_exception(zend_ce_parse_error, error, 0);
 889 }
 890 /* }}} */
 891 
 892 BEGIN_EXTERN_C()
 893 ZEND_API ZEND_COLD void _zend_bailout(char *filename, uint lineno) /* {{{ */
 894 {
 895 
 896         if (!EG(bailout)) {
 897                 zend_output_debug_string(1, "%s(%d) : Bailed out without a bailout address!", filename, lineno);
 898                 exit(-1);
 899         }
 900         CG(unclean_shutdown) = 1;
 901         CG(active_class_entry) = NULL;
 902         CG(in_compilation) = 0;
 903         EG(current_execute_data) = NULL;
 904         LONGJMP(*EG(bailout), FAILURE);
 905 }
 906 /* }}} */
 907 END_EXTERN_C()
 908 
 909 ZEND_API void zend_append_version_info(const zend_extension *extension) /* {{{ */
 910 {
 911         char *new_info;
 912         uint new_info_length;
 913 
 914         new_info_length = (uint)(sizeof("    with  v, , by \n")
 915                                                 + strlen(extension->name)
 916                                                 + strlen(extension->version)
 917                                                 + strlen(extension->copyright)
 918                                                 + strlen(extension->author));
 919 
 920         new_info = (char *) malloc(new_info_length + 1);
 921 
 922         snprintf(new_info, new_info_length, "    with %s v%s, %s, by %s\n", extension->name, extension->version, extension->copyright, extension->author);
 923 
 924         zend_version_info = (char *) realloc(zend_version_info, zend_version_info_length+new_info_length + 1);
 925         strncat(zend_version_info, new_info, new_info_length);
 926         zend_version_info_length += new_info_length;
 927         free(new_info);
 928 }
 929 /* }}} */
 930 
 931 ZEND_API char *get_zend_version(void) /* {{{ */
 932 {
 933         return zend_version_info;
 934 }
 935 /* }}} */
 936 
 937 ZEND_API void zend_activate(void) /* {{{ */
 938 {
 939 #ifdef ZTS
 940         virtual_cwd_activate();
 941 #endif
 942         gc_reset();
 943         init_compiler();
 944         init_executor();
 945         startup_scanner();
 946 }
 947 /* }}} */
 948 
 949 void zend_call_destructors(void) /* {{{ */
 950 {
 951         zend_try {
 952                 shutdown_destructors();
 953         } zend_end_try();
 954 }
 955 /* }}} */
 956 
 957 ZEND_API void zend_deactivate(void) /* {{{ */
 958 {
 959         /* we're no longer executing anything */
 960         EG(current_execute_data) = NULL;
 961 
 962         zend_try {
 963                 shutdown_scanner();
 964         } zend_end_try();
 965 
 966         /* shutdown_executor() takes care of its own bailout handling */
 967         shutdown_executor();
 968 
 969         zend_try {
 970                 zend_ini_deactivate();
 971         } zend_end_try();
 972 
 973         zend_try {
 974                 shutdown_compiler();
 975         } zend_end_try();
 976 
 977         zend_destroy_rsrc_list(&EG(regular_list));
 978 
 979 #if GC_BENCH
 980         fprintf(stderr, "GC Statistics\n");
 981         fprintf(stderr, "-------------\n");
 982         fprintf(stderr, "Runs:               %d\n", GC_G(gc_runs));
 983         fprintf(stderr, "Collected:          %d\n", GC_G(collected));
 984         fprintf(stderr, "Root buffer length: %d\n", GC_G(root_buf_length));
 985         fprintf(stderr, "Root buffer peak:   %d\n\n", GC_G(root_buf_peak));
 986         fprintf(stderr, "      Possible            Remove from  Marked\n");
 987         fprintf(stderr, "        Root    Buffered     buffer     grey\n");
 988         fprintf(stderr, "      --------  --------  -----------  ------\n");
 989         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));
 990 #endif
 991 }
 992 /* }}} */
 993 
 994 BEGIN_EXTERN_C()
 995 ZEND_API void zend_message_dispatcher(zend_long message, const void *data) /* {{{ */
 996 {
 997         if (zend_message_dispatcher_p) {
 998                 zend_message_dispatcher_p(message, data);
 999         }
1000 }
1001 /* }}} */
1002 END_EXTERN_C()
1003 
1004 ZEND_API zval *zend_get_configuration_directive(zend_string *name) /* {{{ */
1005 {
1006         if (zend_get_configuration_directive_p) {
1007                 return zend_get_configuration_directive_p(name);
1008         } else {
1009                 return NULL;
1010         }
1011 }
1012 /* }}} */
1013 
1014 #define SAVE_STACK(stack) do { \
1015                 if (CG(stack).top) { \
1016                         memcpy(&stack, &CG(stack), sizeof(zend_stack)); \
1017                         CG(stack).top = CG(stack).max = 0; \
1018                         CG(stack).elements = NULL; \
1019                 } else { \
1020                         stack.top = 0; \
1021                 } \
1022         } while (0)
1023 
1024 #define RESTORE_STACK(stack) do { \
1025                 if (stack.top) { \
1026                         zend_stack_destroy(&CG(stack)); \
1027                         memcpy(&CG(stack), &stack, sizeof(zend_stack)); \
1028                 } \
1029         } while (0)
1030 
1031 #if !defined(HAVE_NORETURN) || defined(HAVE_NORETURN_ALIAS)
1032 ZEND_API ZEND_COLD void zend_error(int type, const char *format, ...) /* {{{ */
1033 #else
1034 static ZEND_COLD void zend_error_va_list(int type, const char *format, va_list args)
1035 #endif
1036 {
1037         char *str;
1038         int len;
1039 #if !defined(HAVE_NORETURN) || defined(HAVE_NORETURN_ALIAS)
1040         va_list args;
1041 #endif
1042         va_list usr_copy;
1043         zval params[5];
1044         zval retval;
1045         const char *error_filename;
1046         uint error_lineno = 0;
1047         zval orig_user_error_handler;
1048         zend_bool in_compilation;
1049         zend_class_entry *saved_class_entry;
1050         zend_stack loop_var_stack;
1051         zend_stack delayed_oplines_stack;
1052         zend_array *symbol_table;
1053 
1054         /* Report about uncaught exception in case of fatal errors */
1055         if (EG(exception)) {
1056                 zend_execute_data *ex;
1057                 const zend_op *opline;
1058 
1059                 switch (type) {
1060                         case E_CORE_ERROR:
1061                         case E_ERROR:
1062                         case E_RECOVERABLE_ERROR:
1063                         case E_PARSE:
1064                         case E_COMPILE_ERROR:
1065                         case E_USER_ERROR:
1066                                 ex = EG(current_execute_data);
1067                                 opline = NULL;
1068                                 while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
1069                                         ex = ex->prev_execute_data;
1070                                 }
1071                                 if (ex && ex->opline->opcode == ZEND_HANDLE_EXCEPTION &&
1072                                     EG(opline_before_exception)) {
1073                                         opline = EG(opline_before_exception);
1074                                 }
1075                                 zend_exception_error(EG(exception), E_WARNING);
1076                                 EG(exception) = NULL;
1077                                 if (opline) {
1078                                         ex->opline = opline;
1079                                 }
1080                                 break;
1081                         default:
1082                                 break;
1083                 }
1084         }
1085 
1086         /* Obtain relevant filename and lineno */
1087         switch (type) {
1088                 case E_CORE_ERROR:
1089                 case E_CORE_WARNING:
1090                         error_filename = NULL;
1091                         error_lineno = 0;
1092                         break;
1093                 case E_PARSE:
1094                 case E_COMPILE_ERROR:
1095                 case E_COMPILE_WARNING:
1096                 case E_ERROR:
1097                 case E_NOTICE:
1098                 case E_STRICT:
1099                 case E_DEPRECATED:
1100                 case E_WARNING:
1101                 case E_USER_ERROR:
1102                 case E_USER_WARNING:
1103                 case E_USER_NOTICE:
1104                 case E_USER_DEPRECATED:
1105                 case E_RECOVERABLE_ERROR:
1106                         if (zend_is_compiling()) {
1107                                 error_filename = ZSTR_VAL(zend_get_compiled_filename());
1108                                 error_lineno = zend_get_compiled_lineno();
1109                         } else if (zend_is_executing()) {
1110                                 error_filename = zend_get_executed_filename();
1111                                 if (error_filename[0] == '[') { /* [no active file] */
1112                                         error_filename = NULL;
1113                                         error_lineno = 0;
1114                                 } else {
1115                                         error_lineno = zend_get_executed_lineno();
1116                                 }
1117                         } else {
1118                                 error_filename = NULL;
1119                                 error_lineno = 0;
1120                         }
1121                         break;
1122                 default:
1123                         error_filename = NULL;
1124                         error_lineno = 0;
1125                         break;
1126         }
1127         if (!error_filename) {
1128                 error_filename = "Unknown";
1129         }
1130 
1131 #ifdef HAVE_DTRACE
1132         if (DTRACE_ERROR_ENABLED()) {
1133                 char *dtrace_error_buffer;
1134 #if !defined(HAVE_NORETURN) || defined(HAVE_NORETURN_ALIAS)
1135                 va_start(args, format);
1136 #endif
1137                 zend_vspprintf(&dtrace_error_buffer, 0, format, args);
1138                 DTRACE_ERROR(dtrace_error_buffer, (char *)error_filename, error_lineno);
1139                 efree(dtrace_error_buffer);
1140 #if !defined(HAVE_NORETURN) || defined(HAVE_NORETURN_ALIAS)
1141                 va_end(args);
1142 #endif
1143         }
1144 #endif /* HAVE_DTRACE */
1145 
1146 #if !defined(HAVE_NORETURN) || defined(HAVE_NORETURN_ALIAS)
1147         va_start(args, format);
1148 #endif
1149 
1150         /* if we don't have a user defined error handler */
1151         if (Z_TYPE(EG(user_error_handler)) == IS_UNDEF
1152                 || !(EG(user_error_handler_error_reporting) & type)
1153                 || EG(error_handling) != EH_NORMAL) {
1154                 zend_error_cb(type, error_filename, error_lineno, format, args);
1155         } else switch (type) {
1156                 case E_ERROR:
1157                 case E_PARSE:
1158                 case E_CORE_ERROR:
1159                 case E_CORE_WARNING:
1160                 case E_COMPILE_ERROR:
1161                 case E_COMPILE_WARNING:
1162                         /* The error may not be safe to handle in user-space */
1163                         zend_error_cb(type, error_filename, error_lineno, format, args);
1164                         break;
1165                 default:
1166                         /* Handle the error in user space */
1167 /* va_copy() is __va_copy() in old gcc versions.
1168  * According to the autoconf manual, using
1169  * memcpy(&dst, &src, sizeof(va_list))
1170  * gives maximum portability. */
1171 #ifndef va_copy
1172 # ifdef __va_copy
1173 #  define va_copy(dest, src)    __va_copy((dest), (src))
1174 # else
1175 #  define va_copy(dest, src)    memcpy(&(dest), &(src), sizeof(va_list))
1176 # endif
1177 #endif
1178                         va_copy(usr_copy, args);
1179                         len = (int)zend_vspprintf(&str, 0, format, usr_copy);
1180                         ZVAL_NEW_STR(&params[1], zend_string_init(str, len, 0));
1181                         efree(str);
1182 #ifdef va_copy
1183                         va_end(usr_copy);
1184 #endif
1185 
1186                         ZVAL_LONG(&params[0], type);
1187 
1188                         if (error_filename) {
1189                                 ZVAL_STRING(&params[2], error_filename);
1190                         } else {
1191                                 ZVAL_NULL(&params[2]);
1192                         }
1193 
1194                         ZVAL_LONG(&params[3], error_lineno);
1195 
1196                         symbol_table = zend_rebuild_symbol_table();
1197 
1198                         /* during shutdown the symbol table table can be still null */
1199                         if (!symbol_table) {
1200                                 ZVAL_NULL(&params[4]);
1201                         } else {
1202                                 ZVAL_ARR(&params[4], zend_array_dup(symbol_table));
1203                         }
1204 
1205                         ZVAL_COPY_VALUE(&orig_user_error_handler, &EG(user_error_handler));
1206                         ZVAL_UNDEF(&EG(user_error_handler));
1207 
1208                         /* User error handler may include() additinal PHP files.
1209                          * If an error was generated during comilation PHP will compile
1210                          * such scripts recursivly, but some CG() variables may be
1211                          * inconsistent. */
1212 
1213                         in_compilation = CG(in_compilation);
1214                         if (in_compilation) {
1215                                 saved_class_entry = CG(active_class_entry);
1216                                 CG(active_class_entry) = NULL;
1217                                 SAVE_STACK(loop_var_stack);
1218                                 SAVE_STACK(delayed_oplines_stack);
1219                                 CG(in_compilation) = 0;
1220                         }
1221 
1222                         if (call_user_function_ex(CG(function_table), NULL, &orig_user_error_handler, &retval, 5, params, 1, NULL) == SUCCESS) {
1223                                 if (Z_TYPE(retval) != IS_UNDEF) {
1224                                         if (Z_TYPE(retval) == IS_FALSE) {
1225                                                 zend_error_cb(type, error_filename, error_lineno, format, args);
1226                                         }
1227                                         zval_ptr_dtor(&retval);
1228                                 }
1229                         } else if (!EG(exception)) {
1230                                 /* The user error handler failed, use built-in error handler */
1231                                 zend_error_cb(type, error_filename, error_lineno, format, args);
1232                         }
1233 
1234                         if (in_compilation) {
1235                                 CG(active_class_entry) = saved_class_entry;
1236                                 RESTORE_STACK(loop_var_stack);
1237                                 RESTORE_STACK(delayed_oplines_stack);
1238                                 CG(in_compilation) = 1;
1239                         }
1240 
1241                         zval_ptr_dtor(&params[4]);
1242                         zval_ptr_dtor(&params[3]);
1243                         zval_ptr_dtor(&params[2]);
1244                         zval_ptr_dtor(&params[1]);
1245                         zval_ptr_dtor(&params[0]);
1246 
1247                         if (Z_TYPE(EG(user_error_handler)) == IS_UNDEF) {
1248                                 ZVAL_COPY_VALUE(&EG(user_error_handler), &orig_user_error_handler);
1249                         } else {
1250                                 zval_ptr_dtor(&orig_user_error_handler);
1251                         }
1252                         break;
1253         }
1254 
1255 #if !defined(HAVE_NORETURN) || defined(HAVE_NORETURN_ALIAS)
1256         va_end(args);
1257 #endif
1258 
1259         if (type == E_PARSE) {
1260                 /* eval() errors do not affect exit_status */
1261                 if (!(EG(current_execute_data) &&
1262                         EG(current_execute_data)->func &&
1263                         ZEND_USER_CODE(EG(current_execute_data)->func->type) &&
1264                         EG(current_execute_data)->opline->opcode == ZEND_INCLUDE_OR_EVAL &&
1265                         EG(current_execute_data)->opline->extended_value == ZEND_EVAL)) {
1266                         EG(exit_status) = 255;
1267                 }
1268         }
1269 }
1270 /* }}} */
1271 
1272 #ifdef HAVE_NORETURN
1273 # ifdef HAVE_NORETURN_ALIAS
1274 ZEND_COLD void zend_error_noreturn(int type, const char *format, ...) __attribute__ ((alias("zend_error"),noreturn));
1275 # else
1276 ZEND_API ZEND_COLD void zend_error(int type, const char *format, ...) /* {{{ */
1277 {
1278         va_list va;
1279 
1280         va_start(va, format);
1281         zend_error_va_list(type, format, va);
1282         va_end(va);
1283 }
1284 
1285 ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char *format, ...)
1286 {
1287         va_list va;
1288 
1289         va_start(va, format);
1290         zend_error_va_list(type, format, va);
1291         va_end(va);
1292 }
1293 /* }}} */
1294 # endif
1295 #endif
1296 
1297 ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format, ...) /* {{{ */
1298 {
1299         va_list va;
1300         char *message = NULL;
1301         
1302         if (exception_ce) {
1303                 if (!instanceof_function(exception_ce, zend_ce_error)) {
1304                         zend_error(E_NOTICE, "Error exceptions must be derived from Error");
1305                         exception_ce = zend_ce_error;
1306                 }
1307         } else {
1308                 exception_ce = zend_ce_error;
1309         }
1310 
1311         va_start(va, format);
1312         zend_vspprintf(&message, 0, format, va);
1313 
1314         //TODO: we can't convert compile-time errors to exceptions yet???
1315         if (EG(current_execute_data) && !CG(in_compilation)) {
1316                 zend_throw_exception(exception_ce, message, 0);
1317         } else {
1318                 zend_error(E_ERROR, "%s", message);
1319         }
1320 
1321         efree(message);
1322         va_end(va);
1323 }
1324 /* }}} */
1325 
1326 ZEND_API ZEND_COLD void zend_type_error(const char *format, ...) /* {{{ */
1327 {
1328         va_list va;
1329         char *message = NULL;
1330 
1331         va_start(va, format);
1332         zend_vspprintf(&message, 0, format, va);
1333         zend_throw_exception(zend_ce_type_error, message, 0);
1334         efree(message);
1335         va_end(va);
1336 } /* }}} */
1337 
1338 ZEND_API ZEND_COLD void zend_internal_type_error(zend_bool throw_exception, const char *format, ...) /* {{{ */
1339 {
1340         va_list va;
1341         char *message = NULL;
1342 
1343         va_start(va, format);
1344         zend_vspprintf(&message, 0, format, va);
1345         if (throw_exception) {
1346                 zend_throw_exception(zend_ce_type_error, message, 0);
1347         } else {
1348                 zend_error(E_WARNING, "%s", message);
1349         }
1350         efree(message);
1351 
1352         va_end(va);
1353 } /* }}} */
1354 
1355 ZEND_API ZEND_COLD void zend_output_debug_string(zend_bool trigger_break, const char *format, ...) /* {{{ */
1356 {
1357 #if ZEND_DEBUG
1358         va_list args;
1359 
1360         va_start(args, format);
1361 #       ifdef ZEND_WIN32
1362         {
1363                 char output_buf[1024];
1364 
1365                 vsnprintf(output_buf, 1024, format, args);
1366                 OutputDebugString(output_buf);
1367                 OutputDebugString("\n");
1368                 if (trigger_break && IsDebuggerPresent()) {
1369                         DebugBreak();
1370                 }
1371         }
1372 #       else
1373         vfprintf(stderr, format, args);
1374         fprintf(stderr, "\n");
1375 #       endif
1376         va_end(args);
1377 #endif
1378 }
1379 /* }}} */
1380 
1381 ZEND_API void zend_try_exception_handler() /* {{{ */
1382 {
1383         if (EG(exception)) {
1384                 if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
1385                         zval orig_user_exception_handler;
1386                         zval params[1], retval2;
1387                         zend_object *old_exception;
1388                         old_exception = EG(exception);
1389                         EG(exception) = NULL;
1390                         ZVAL_OBJ(&params[0], old_exception);
1391                         ZVAL_COPY_VALUE(&orig_user_exception_handler, &EG(user_exception_handler));
1392 
1393                         if (call_user_function_ex(CG(function_table), NULL, &orig_user_exception_handler, &retval2, 1, params, 1, NULL) == SUCCESS) {
1394                                 zval_ptr_dtor(&retval2);
1395                                 if (EG(exception)) {
1396                                         OBJ_RELEASE(EG(exception));
1397                                         EG(exception) = NULL;
1398                                 }
1399                                 OBJ_RELEASE(old_exception);
1400                         } else {
1401                                 EG(exception) = old_exception;
1402                         }
1403                 }
1404         }
1405 } /* }}} */
1406 
1407 ZEND_API int zend_execute_scripts(int type, zval *retval, int file_count, ...) /* {{{ */
1408 {
1409         va_list files;
1410         int i;
1411         zend_file_handle *file_handle;
1412         zend_op_array *op_array;
1413 
1414         va_start(files, file_count);
1415         for (i = 0; i < file_count; i++) {
1416                 file_handle = va_arg(files, zend_file_handle *);
1417                 if (!file_handle) {
1418                         continue;
1419                 }
1420 
1421                 op_array = zend_compile_file(file_handle, type);
1422                 if (file_handle->opened_path) {
1423                         zend_hash_add_empty_element(&EG(included_files), file_handle->opened_path);
1424                 }
1425                 zend_destroy_file_handle(file_handle);
1426                 if (op_array) {
1427                         zend_execute(op_array, retval);
1428                         zend_exception_restore();
1429                         zend_try_exception_handler();
1430                         if (EG(exception)) {
1431                                 zend_exception_error(EG(exception), E_ERROR);
1432                         }
1433                         destroy_op_array(op_array);
1434                         efree_size(op_array, sizeof(zend_op_array));
1435                 } else if (type==ZEND_REQUIRE) {
1436                         va_end(files);
1437                         return FAILURE;
1438                 }
1439         }
1440         va_end(files);
1441 
1442         return SUCCESS;
1443 }
1444 /* }}} */
1445 
1446 #define COMPILED_STRING_DESCRIPTION_FORMAT "%s(%d) : %s"
1447 
1448 ZEND_API char *zend_make_compiled_string_description(const char *name) /* {{{ */
1449 {
1450         const char *cur_filename;
1451         int cur_lineno;
1452         char *compiled_string_description;
1453 
1454         if (zend_is_compiling()) {
1455                 cur_filename = ZSTR_VAL(zend_get_compiled_filename());
1456                 cur_lineno = zend_get_compiled_lineno();
1457         } else if (zend_is_executing()) {
1458                 cur_filename = zend_get_executed_filename();
1459                 cur_lineno = zend_get_executed_lineno();
1460         } else {
1461                 cur_filename = "Unknown";
1462                 cur_lineno = 0;
1463         }
1464 
1465         zend_spprintf(&compiled_string_description, 0, COMPILED_STRING_DESCRIPTION_FORMAT, cur_filename, cur_lineno, name);
1466         return compiled_string_description;
1467 }
1468 /* }}} */
1469 
1470 void free_estring(char **str_p) /* {{{ */
1471 {
1472         efree(*str_p);
1473 }
1474 /* }}} */
1475 
1476 /*
1477  * Local variables:
1478  * tab-width: 4
1479  * c-basic-offset: 4
1480  * indent-tabs-mode: t
1481  * End:
1482  */

/* [<][>][^][v][top][bottom][index][help] */