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

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