Back to index

php5  5.3.10
zend.c
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | Zend Engine                                                          |
00004    +----------------------------------------------------------------------+
00005    | Copyright (c) 1998-2012 Zend Technologies Ltd. (http://www.zend.com) |
00006    +----------------------------------------------------------------------+
00007    | This source file is subject to version 2.00 of the Zend license,     |
00008    | that is bundled with this package in the file LICENSE, and is        |
00009    | available through the world-wide-web at the following url:           |
00010    | http://www.zend.com/license/2_00.txt.                                |
00011    | If you did not receive a copy of the Zend license and are unable to  |
00012    | obtain it through the world-wide-web, please send a note to          |
00013    | license@zend.com so we can mail you a copy immediately.              |
00014    +----------------------------------------------------------------------+
00015    | Authors: Andi Gutmans <andi@zend.com>                                |
00016    |          Zeev Suraski <zeev@zend.com>                                |
00017    +----------------------------------------------------------------------+
00018 */
00019 
00020 /* $Id: zend.c 321634 2012-01-01 13:15:04Z felipe $ */
00021 
00022 #include "zend.h"
00023 #include "zend_extensions.h"
00024 #include "zend_modules.h"
00025 #include "zend_constants.h"
00026 #include "zend_list.h"
00027 #include "zend_API.h"
00028 #include "zend_exceptions.h"
00029 #include "zend_builtin_functions.h"
00030 #include "zend_ini.h"
00031 #include "zend_vm.h"
00032 
00033 #ifdef ZTS
00034 # define GLOBAL_FUNCTION_TABLE            global_function_table
00035 # define GLOBAL_CLASS_TABLE               global_class_table
00036 # define GLOBAL_CONSTANTS_TABLE           global_constants_table
00037 # define GLOBAL_AUTO_GLOBALS_TABLE global_auto_globals_table
00038 #else
00039 # define GLOBAL_FUNCTION_TABLE            CG(function_table)
00040 # define GLOBAL_CLASS_TABLE               CG(class_table)
00041 # define GLOBAL_AUTO_GLOBALS_TABLE CG(auto_globals)
00042 # define GLOBAL_CONSTANTS_TABLE           EG(zend_constants)
00043 #endif
00044 
00045 #if defined(ZEND_WIN32) && ZEND_DEBUG
00046 BOOL WINAPI IsDebuggerPresent(VOID);
00047 #endif
00048 
00049 /* true multithread-shared globals */
00050 ZEND_API zend_class_entry *zend_standard_class_def = NULL;
00051 ZEND_API int (*zend_printf)(const char *format, ...);
00052 ZEND_API zend_write_func_t zend_write;
00053 ZEND_API FILE *(*zend_fopen)(const char *filename, char **opened_path TSRMLS_DC);
00054 ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC);
00055 ZEND_API void (*zend_block_interruptions)(void);
00056 ZEND_API void (*zend_unblock_interruptions)(void);
00057 ZEND_API void (*zend_ticks_function)(int ticks);
00058 ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
00059 int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
00060 ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);
00061 ZEND_API char *(*zend_resolve_path)(const char *filename, int filename_len TSRMLS_DC);
00062 
00063 void (*zend_on_timeout)(int seconds TSRMLS_DC);
00064 
00065 static void (*zend_message_dispatcher_p)(long message, void *data TSRMLS_DC);
00066 static int (*zend_get_configuration_directive_p)(const char *name, uint name_length, zval *contents);
00067 
00068 static ZEND_INI_MH(OnUpdateErrorReporting) /* {{{ */
00069 {
00070        if (!new_value) {
00071               EG(error_reporting) = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED;
00072        } else {
00073               EG(error_reporting) = atoi(new_value);
00074        }
00075        return SUCCESS;
00076 }
00077 /* }}} */
00078 
00079 static ZEND_INI_MH(OnUpdateGCEnabled) /* {{{ */
00080 {
00081        OnUpdateBool(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
00082 
00083        if (GC_G(gc_enabled)) {
00084               gc_init(TSRMLS_C);
00085        }
00086 
00087        return SUCCESS;
00088 }
00089 /* }}} */
00090 
00091 ZEND_INI_BEGIN()
00092        ZEND_INI_ENTRY("error_reporting",                       NULL,         ZEND_INI_ALL,        OnUpdateErrorReporting)
00093        STD_ZEND_INI_BOOLEAN("zend.enable_gc",                         "1",   ZEND_INI_ALL,        OnUpdateGCEnabled,      gc_enabled,     zend_gc_globals,        gc_globals)
00094 #ifdef ZEND_MULTIBYTE
00095        STD_ZEND_INI_BOOLEAN("detect_unicode", "1", ZEND_INI_ALL, OnUpdateBool, detect_unicode, zend_compiler_globals, compiler_globals)
00096 #endif
00097 ZEND_INI_END()
00098 
00099 
00100 #ifdef ZTS
00101 ZEND_API int compiler_globals_id;
00102 ZEND_API int executor_globals_id;
00103 static HashTable *global_function_table = NULL;
00104 static HashTable *global_class_table = NULL;
00105 static HashTable *global_constants_table = NULL;
00106 static HashTable *global_auto_globals_table = NULL;
00107 static HashTable *global_persistent_list = NULL;
00108 #endif
00109 
00110 ZEND_API zend_utility_values zend_uv;
00111 
00112 ZEND_API zval zval_used_for_init; /* True global variable */
00113 
00114 /* version information */
00115 static char *zend_version_info;
00116 static uint zend_version_info_length;
00117 #define ZEND_CORE_VERSION_INFO     "Zend Engine v" ZEND_VERSION ", Copyright (c) 1998-2012 Zend Technologies\n"
00118 #define PRINT_ZVAL_INDENT 4
00119 
00120 static void print_hash(zend_write_func_t write_func, HashTable *ht, int indent, zend_bool is_object TSRMLS_DC) /* {{{ */
00121 {
00122        zval **tmp;
00123        char *string_key;
00124        HashPosition iterator;
00125        ulong num_key;
00126        uint str_len;
00127        int i;
00128 
00129        for (i = 0; i < indent; i++) {
00130               ZEND_PUTS_EX(" ");
00131        }
00132        ZEND_PUTS_EX("(\n");
00133        indent += PRINT_ZVAL_INDENT;
00134        zend_hash_internal_pointer_reset_ex(ht, &iterator);
00135        while (zend_hash_get_current_data_ex(ht, (void **) &tmp, &iterator) == SUCCESS) {
00136               for (i = 0; i < indent; i++) {
00137                      ZEND_PUTS_EX(" ");
00138               }
00139               ZEND_PUTS_EX("[");
00140               switch (zend_hash_get_current_key_ex(ht, &string_key, &str_len, &num_key, 0, &iterator)) {
00141                      case HASH_KEY_IS_STRING:
00142                             if (is_object) {
00143                                    char *prop_name, *class_name;
00144                                    int mangled = zend_unmangle_property_name(string_key, str_len - 1, &class_name, &prop_name);
00145 
00146                                    ZEND_PUTS_EX(prop_name);
00147                                    if (class_name && mangled == SUCCESS) {
00148                                           if (class_name[0]=='*') {
00149                                                  ZEND_PUTS_EX(":protected");
00150                                           } else {
00151                                                  ZEND_PUTS_EX(":");
00152                                                  ZEND_PUTS_EX(class_name);
00153                                                  ZEND_PUTS_EX(":private");
00154                                           }
00155                                    }
00156                             } else {
00157                                    ZEND_WRITE_EX(string_key, str_len-1);
00158                             }
00159                             break;
00160                      case HASH_KEY_IS_LONG:
00161                             {
00162                                    char key[25];
00163                                    snprintf(key, sizeof(key), "%ld", num_key);
00164                                    ZEND_PUTS_EX(key);
00165                             }
00166                             break;
00167               }
00168               ZEND_PUTS_EX("] => ");
00169               zend_print_zval_r_ex(write_func, *tmp, indent+PRINT_ZVAL_INDENT TSRMLS_CC);
00170               ZEND_PUTS_EX("\n");
00171               zend_hash_move_forward_ex(ht, &iterator);
00172        }
00173        indent -= PRINT_ZVAL_INDENT;
00174        for (i = 0; i < indent; i++) {
00175               ZEND_PUTS_EX(" ");
00176        }
00177        ZEND_PUTS_EX(")\n");
00178 }
00179 /* }}} */
00180 
00181 static void print_flat_hash(HashTable *ht TSRMLS_DC) /* {{{ */
00182 {
00183        zval **tmp;
00184        char *string_key;
00185        HashPosition iterator;
00186        ulong num_key;
00187        uint str_len;
00188        int i = 0;
00189 
00190        zend_hash_internal_pointer_reset_ex(ht, &iterator);
00191        while (zend_hash_get_current_data_ex(ht, (void **) &tmp, &iterator) == SUCCESS) {
00192               if (i++ > 0) {
00193                      ZEND_PUTS(",");
00194               }
00195               ZEND_PUTS("[");
00196               switch (zend_hash_get_current_key_ex(ht, &string_key, &str_len, &num_key, 0, &iterator)) {
00197                      case HASH_KEY_IS_STRING:
00198                             ZEND_PUTS(string_key);
00199                             break;
00200                      case HASH_KEY_IS_LONG:
00201                             zend_printf("%ld", num_key);
00202                             break;
00203               }
00204               ZEND_PUTS("] => ");
00205               zend_print_flat_zval_r(*tmp TSRMLS_CC);
00206               zend_hash_move_forward_ex(ht, &iterator);
00207        }
00208 }
00209 /* }}} */
00210 
00211 ZEND_API void zend_make_printable_zval(zval *expr, zval *expr_copy, int *use_copy) /* {{{ */
00212 {
00213        if (Z_TYPE_P(expr)==IS_STRING) {
00214               *use_copy = 0;
00215               return;
00216        }
00217        switch (Z_TYPE_P(expr)) {
00218               case IS_NULL:
00219                      Z_STRLEN_P(expr_copy) = 0;
00220                      Z_STRVAL_P(expr_copy) = STR_EMPTY_ALLOC();
00221                      break;
00222               case IS_BOOL:
00223                      if (Z_LVAL_P(expr)) {
00224                             Z_STRLEN_P(expr_copy) = 1;
00225                             Z_STRVAL_P(expr_copy) = estrndup("1", 1);
00226                      } else {
00227                             Z_STRLEN_P(expr_copy) = 0;
00228                             Z_STRVAL_P(expr_copy) = STR_EMPTY_ALLOC();
00229                      }
00230                      break;
00231               case IS_RESOURCE:
00232                      Z_STRVAL_P(expr_copy) = (char *) emalloc(sizeof("Resource id #") - 1 + MAX_LENGTH_OF_LONG);
00233                      Z_STRLEN_P(expr_copy) = sprintf(Z_STRVAL_P(expr_copy), "Resource id #%ld", Z_LVAL_P(expr));
00234                      break;
00235               case IS_ARRAY:
00236                      Z_STRLEN_P(expr_copy) = sizeof("Array") - 1;
00237                      Z_STRVAL_P(expr_copy) = estrndup("Array", Z_STRLEN_P(expr_copy));
00238                      break;
00239               case IS_OBJECT:
00240                      {
00241                             TSRMLS_FETCH();
00242 
00243                             if (Z_OBJ_HANDLER_P(expr, cast_object) && Z_OBJ_HANDLER_P(expr, cast_object)(expr, expr_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
00244                                    break;
00245                             }
00246                             /* Standard PHP objects */
00247                             if (Z_OBJ_HT_P(expr) == &std_object_handlers || !Z_OBJ_HANDLER_P(expr, cast_object)) {
00248                                    if (zend_std_cast_object_tostring(expr, expr_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
00249                                           break;
00250                                    }
00251                             }
00252                             if (!Z_OBJ_HANDLER_P(expr, cast_object) && Z_OBJ_HANDLER_P(expr, get)) {
00253                                    zval *z = Z_OBJ_HANDLER_P(expr, get)(expr TSRMLS_CC);
00254 
00255                                    Z_ADDREF_P(z);
00256                                    if (Z_TYPE_P(z) != IS_OBJECT) {
00257                                           zend_make_printable_zval(z, expr_copy, use_copy);
00258                                           if (*use_copy) {
00259                                                  zval_ptr_dtor(&z);
00260                                           } else {
00261                                                  ZVAL_ZVAL(expr_copy, z, 0, 1);
00262                                                  *use_copy = 1;
00263                                           }
00264                                           return;
00265                                    }
00266                                    zval_ptr_dtor(&z);
00267                             }
00268                             zend_error(EG(exception) ? E_ERROR : E_RECOVERABLE_ERROR, "Object of class %s could not be converted to string", Z_OBJCE_P(expr)->name);
00269                             Z_STRLEN_P(expr_copy) = 0;
00270                             Z_STRVAL_P(expr_copy) = STR_EMPTY_ALLOC();
00271                      }
00272                      break;
00273               case IS_DOUBLE:
00274                      *expr_copy = *expr;
00275                      zval_copy_ctor(expr_copy);
00276                      zend_locale_sprintf_double(expr_copy ZEND_FILE_LINE_CC);
00277                      break;
00278               default:
00279                      *expr_copy = *expr;
00280                      zval_copy_ctor(expr_copy);
00281                      convert_to_string(expr_copy);
00282                      break;
00283        }
00284        Z_TYPE_P(expr_copy) = IS_STRING;
00285        *use_copy = 1;
00286 }
00287 /* }}} */
00288 
00289 ZEND_API int zend_print_zval(zval *expr, int indent) /* {{{ */
00290 {
00291        return zend_print_zval_ex(zend_write, expr, indent);
00292 }
00293 /* }}} */
00294 
00295 ZEND_API int zend_print_zval_ex(zend_write_func_t write_func, zval *expr, int indent) /* {{{ */
00296 {
00297        zval expr_copy;
00298        int use_copy;
00299 
00300        zend_make_printable_zval(expr, &expr_copy, &use_copy);
00301        if (use_copy) {
00302               expr = &expr_copy;
00303        }
00304        if (Z_STRLEN_P(expr) == 0) { /* optimize away empty strings */
00305               if (use_copy) {
00306                      zval_dtor(expr);
00307               }
00308               return 0;
00309        }
00310        write_func(Z_STRVAL_P(expr), Z_STRLEN_P(expr));
00311        if (use_copy) {
00312               zval_dtor(expr);
00313        }
00314        return Z_STRLEN_P(expr);
00315 }
00316 /* }}} */
00317 
00318 ZEND_API void zend_print_flat_zval_r(zval *expr TSRMLS_DC) /* {{{ */
00319 {
00320        switch (Z_TYPE_P(expr)) {
00321               case IS_ARRAY:
00322                      ZEND_PUTS("Array (");
00323                      if (++Z_ARRVAL_P(expr)->nApplyCount>1) {
00324                             ZEND_PUTS(" *RECURSION*");
00325                             Z_ARRVAL_P(expr)->nApplyCount--;
00326                             return;
00327                      }
00328                      print_flat_hash(Z_ARRVAL_P(expr) TSRMLS_CC);
00329                      ZEND_PUTS(")");
00330                      Z_ARRVAL_P(expr)->nApplyCount--;
00331                      break;
00332               case IS_OBJECT:
00333               {
00334                      HashTable *properties = NULL;
00335                      char *class_name = NULL;
00336                      zend_uint clen;
00337 
00338                      if (Z_OBJ_HANDLER_P(expr, get_class_name)) {
00339                             Z_OBJ_HANDLER_P(expr, get_class_name)(expr, &class_name, &clen, 0 TSRMLS_CC);
00340                      }
00341                      if (class_name) {
00342                             zend_printf("%s Object (", class_name);
00343                      } else {
00344                             zend_printf("%s Object (", "Unknown Class");
00345                      }
00346                      if (class_name) {
00347                             efree(class_name);
00348                      }
00349                      if (Z_OBJ_HANDLER_P(expr, get_properties)) {
00350                             properties = Z_OBJPROP_P(expr);
00351                      }
00352                      if (properties) {
00353                             if (++properties->nApplyCount>1) {
00354                                    ZEND_PUTS(" *RECURSION*");
00355                                    properties->nApplyCount--;
00356                                    return;
00357                             }
00358                             print_flat_hash(properties TSRMLS_CC);
00359                             properties->nApplyCount--;
00360                      }
00361                      ZEND_PUTS(")");
00362                      break;
00363               }
00364               default:
00365                      zend_print_variable(expr);
00366                      break;
00367        }
00368 }
00369 /* }}} */
00370 
00371 ZEND_API void zend_print_zval_r(zval *expr, int indent TSRMLS_DC) /* {{{ */
00372 {
00373        zend_print_zval_r_ex(zend_write, expr, indent TSRMLS_CC);
00374 }
00375 /* }}} */
00376 
00377 ZEND_API void zend_print_zval_r_ex(zend_write_func_t write_func, zval *expr, int indent TSRMLS_DC) /* {{{ */
00378 {
00379        switch (Z_TYPE_P(expr)) {
00380               case IS_ARRAY:
00381                      ZEND_PUTS_EX("Array\n");
00382                      if (++Z_ARRVAL_P(expr)->nApplyCount>1) {
00383                             ZEND_PUTS_EX(" *RECURSION*");
00384                             Z_ARRVAL_P(expr)->nApplyCount--;
00385                             return;
00386                      }
00387                      print_hash(write_func, Z_ARRVAL_P(expr), indent, 0 TSRMLS_CC);
00388                      Z_ARRVAL_P(expr)->nApplyCount--;
00389                      break;
00390               case IS_OBJECT:
00391                      {
00392                             HashTable *properties;
00393                             char *class_name = NULL;
00394                             zend_uint clen;
00395                             int is_temp;
00396 
00397                             if (Z_OBJ_HANDLER_P(expr, get_class_name)) {
00398                                    Z_OBJ_HANDLER_P(expr, get_class_name)(expr, &class_name, &clen, 0 TSRMLS_CC);
00399                             }
00400                             if (class_name) {
00401                                    ZEND_PUTS_EX(class_name);
00402                             } else {
00403                                    ZEND_PUTS_EX("Unknown Class");
00404                             }
00405                             ZEND_PUTS_EX(" Object\n");
00406                             if (class_name) {
00407                                    efree(class_name);
00408                             }
00409                             if ((properties = Z_OBJDEBUG_P(expr, is_temp)) == NULL) {
00410                                    break;
00411                             }
00412                             if (++properties->nApplyCount>1) {
00413                                    ZEND_PUTS_EX(" *RECURSION*");
00414                                    properties->nApplyCount--;
00415                                    return;
00416                             }
00417                             print_hash(write_func, properties, indent, 1 TSRMLS_CC);
00418                             properties->nApplyCount--;
00419                             if (is_temp) {
00420                                    zend_hash_destroy(properties);
00421                                    efree(properties);
00422                             }
00423                             break;
00424                      }
00425               default:
00426                      zend_print_zval_ex(write_func, expr, indent);
00427                      break;
00428        }
00429 }
00430 /* }}} */
00431 
00432 static FILE *zend_fopen_wrapper(const char *filename, char **opened_path TSRMLS_DC) /* {{{ */
00433 {
00434        if (opened_path) {
00435               *opened_path = estrdup(filename);
00436        }
00437        return fopen(filename, "rb");
00438 }
00439 /* }}} */
00440 
00441 #ifdef ZTS
00442 static zend_bool asp_tags_default           = 0;
00443 static zend_bool short_tags_default                = 1;
00444 static zend_bool ct_pass_ref_default        = 1;
00445 static zend_uint compiler_options_default = ZEND_COMPILE_DEFAULT;
00446 #else
00447 # define asp_tags_default                 0
00448 # define short_tags_default               1
00449 # define ct_pass_ref_default              1
00450 # define compiler_options_default  ZEND_COMPILE_DEFAULT
00451 #endif
00452 
00453 static void zend_set_default_compile_time_values(TSRMLS_D) /* {{{ */
00454 {
00455        /* default compile-time values */
00456        CG(asp_tags) = asp_tags_default;
00457        CG(short_tags) = short_tags_default;
00458        CG(allow_call_time_pass_reference) = ct_pass_ref_default;
00459        CG(compiler_options) = compiler_options_default;
00460 }
00461 /* }}} */
00462 
00463 static void zend_init_exception_op(TSRMLS_D) /* {{{ */
00464 {
00465        memset(EG(exception_op), 0, sizeof(EG(exception_op)));
00466        EG(exception_op)[0].opcode = ZEND_HANDLE_EXCEPTION;
00467        EG(exception_op)[0].op1.op_type = IS_UNUSED;
00468        EG(exception_op)[0].op2.op_type = IS_UNUSED;
00469        EG(exception_op)[0].result.op_type = IS_UNUSED;
00470        ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op));
00471        EG(exception_op)[1].opcode = ZEND_HANDLE_EXCEPTION;
00472        EG(exception_op)[1].op1.op_type = IS_UNUSED;
00473        EG(exception_op)[1].op2.op_type = IS_UNUSED;
00474        EG(exception_op)[1].result.op_type = IS_UNUSED;
00475        ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op)+1);
00476        EG(exception_op)[2].opcode = ZEND_HANDLE_EXCEPTION;
00477        EG(exception_op)[2].op1.op_type = IS_UNUSED;
00478        EG(exception_op)[2].op2.op_type = IS_UNUSED;
00479        EG(exception_op)[2].result.op_type = IS_UNUSED;
00480        ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op)+2);
00481 }
00482 /* }}} */
00483 
00484 #ifdef ZTS
00485 static void compiler_globals_ctor(zend_compiler_globals *compiler_globals TSRMLS_DC) /* {{{ */
00486 {
00487        zend_function tmp_func;
00488        zend_class_entry *tmp_class;
00489 
00490        compiler_globals->compiled_filename = NULL;
00491 
00492        compiler_globals->function_table = (HashTable *) malloc(sizeof(HashTable));
00493        zend_hash_init_ex(compiler_globals->function_table, 100, NULL, ZEND_FUNCTION_DTOR, 1, 0);
00494        zend_hash_copy(compiler_globals->function_table, global_function_table, NULL, &tmp_func, sizeof(zend_function));
00495 
00496        compiler_globals->class_table = (HashTable *) malloc(sizeof(HashTable));
00497        zend_hash_init_ex(compiler_globals->class_table, 10, NULL, ZEND_CLASS_DTOR, 1, 0);
00498        zend_hash_copy(compiler_globals->class_table, global_class_table, (copy_ctor_func_t) zend_class_add_ref, &tmp_class, sizeof(zend_class_entry *));
00499 
00500        zend_set_default_compile_time_values(TSRMLS_C);
00501 
00502        CG(interactive) = 0;
00503 
00504        compiler_globals->auto_globals = (HashTable *) malloc(sizeof(HashTable));
00505        zend_hash_init_ex(compiler_globals->auto_globals, 8, NULL, NULL, 1, 0);
00506        zend_hash_copy(compiler_globals->auto_globals, global_auto_globals_table, NULL, NULL, sizeof(zend_auto_global) /* empty element */);
00507 
00508        compiler_globals->last_static_member = zend_hash_num_elements(compiler_globals->class_table);
00509        if (compiler_globals->last_static_member) {
00510               compiler_globals->static_members = (HashTable**)calloc(compiler_globals->last_static_member, sizeof(HashTable*));
00511        } else {
00512               compiler_globals->static_members = NULL;
00513        }
00514 }
00515 /* }}} */
00516 
00517 static void compiler_globals_dtor(zend_compiler_globals *compiler_globals TSRMLS_DC) /* {{{ */
00518 {
00519        if (compiler_globals->function_table != GLOBAL_FUNCTION_TABLE) {
00520               zend_hash_destroy(compiler_globals->function_table);
00521               free(compiler_globals->function_table);
00522        }
00523        if (compiler_globals->class_table != GLOBAL_CLASS_TABLE) {
00524               zend_hash_destroy(compiler_globals->class_table);
00525               free(compiler_globals->class_table);
00526        }
00527        if (compiler_globals->auto_globals != GLOBAL_AUTO_GLOBALS_TABLE) {
00528               zend_hash_destroy(compiler_globals->auto_globals);
00529               free(compiler_globals->auto_globals);
00530        }
00531        if (compiler_globals->static_members) {
00532               free(compiler_globals->static_members);
00533        }
00534        compiler_globals->last_static_member = 0;
00535 }
00536 /* }}} */
00537 
00538 static void executor_globals_ctor(zend_executor_globals *executor_globals TSRMLS_DC) /* {{{ */
00539 {
00540        zend_startup_constants(TSRMLS_C);
00541        zend_copy_constants(EG(zend_constants), GLOBAL_CONSTANTS_TABLE);
00542        zend_init_rsrc_plist(TSRMLS_C);
00543        zend_init_exception_op(TSRMLS_C);
00544        EG(lambda_count) = 0;
00545        EG(user_error_handler) = NULL;
00546        EG(user_exception_handler) = NULL;
00547        EG(in_execution) = 0;
00548        EG(in_autoload) = NULL;
00549        EG(current_execute_data) = NULL;
00550        EG(current_module) = NULL;
00551        EG(exit_status) = 0;
00552        EG(saved_fpu_cw) = NULL;
00553        EG(active) = 0;
00554 }
00555 /* }}} */
00556 
00557 static void executor_globals_dtor(zend_executor_globals *executor_globals TSRMLS_DC) /* {{{ */
00558 {
00559        zend_ini_shutdown(TSRMLS_C);
00560        if (&executor_globals->persistent_list != global_persistent_list) {
00561               zend_destroy_rsrc_list(&executor_globals->persistent_list TSRMLS_CC);
00562        }
00563        if (executor_globals->zend_constants != GLOBAL_CONSTANTS_TABLE) {
00564               zend_hash_destroy(executor_globals->zend_constants);
00565               free(executor_globals->zend_constants);
00566        }
00567 }
00568 /* }}} */
00569 
00570 static void zend_new_thread_end_handler(THREAD_T thread_id TSRMLS_DC) /* {{{ */
00571 {
00572        if (zend_copy_ini_directives(TSRMLS_C) == SUCCESS) {
00573               zend_ini_refresh_caches(ZEND_INI_STAGE_STARTUP TSRMLS_CC);
00574        }
00575 }
00576 /* }}} */
00577 #endif
00578 
00579 #if defined(__FreeBSD__) || defined(__DragonFly__)
00580 /* FreeBSD and DragonFly floating point precision fix */
00581 #include <floatingpoint.h>
00582 #endif
00583 
00584 static void ini_scanner_globals_ctor(zend_ini_scanner_globals *scanner_globals_p TSRMLS_DC) /* {{{ */
00585 {
00586        memset(scanner_globals_p, 0, sizeof(*scanner_globals_p));
00587 }
00588 /* }}} */
00589 
00590 static void php_scanner_globals_ctor(zend_php_scanner_globals *scanner_globals_p TSRMLS_DC) /* {{{ */
00591 {
00592        memset(scanner_globals_p, 0, sizeof(*scanner_globals_p));
00593 }
00594 /* }}} */
00595 
00596 void zend_init_opcodes_handlers(void);
00597 
00598 int zend_startup(zend_utility_functions *utility_functions, char **extensions TSRMLS_DC) /* {{{ */
00599 {
00600 #ifdef ZTS
00601        zend_compiler_globals *compiler_globals;
00602        zend_executor_globals *executor_globals;
00603        extern ZEND_API ts_rsrc_id ini_scanner_globals_id;
00604        extern ZEND_API ts_rsrc_id language_scanner_globals_id;
00605 #else
00606        extern zend_ini_scanner_globals ini_scanner_globals;
00607        extern zend_php_scanner_globals language_scanner_globals;
00608 #endif
00609 
00610        start_memory_manager(TSRMLS_C);
00611 
00612 #if defined(__FreeBSD__) || defined(__DragonFly__)
00613        /* FreeBSD and DragonFly floating point precision fix */
00614        fpsetmask(0);
00615 #endif
00616 
00617        zend_startup_strtod();
00618        zend_startup_extensions_mechanism();
00619 
00620        /* Set up utility functions and values */
00621        zend_error_cb = utility_functions->error_function;
00622        zend_printf = utility_functions->printf_function;
00623        zend_write = (zend_write_func_t) utility_functions->write_function;
00624        zend_fopen = utility_functions->fopen_function;
00625        if (!zend_fopen) {
00626               zend_fopen = zend_fopen_wrapper;
00627        }
00628        zend_stream_open_function = utility_functions->stream_open_function;
00629        zend_message_dispatcher_p = utility_functions->message_handler;
00630        zend_block_interruptions = utility_functions->block_interruptions;
00631        zend_unblock_interruptions = utility_functions->unblock_interruptions;
00632        zend_get_configuration_directive_p = utility_functions->get_configuration_directive;
00633        zend_ticks_function = utility_functions->ticks_function;
00634        zend_on_timeout = utility_functions->on_timeout;
00635        zend_vspprintf = utility_functions->vspprintf_function;
00636        zend_getenv = utility_functions->getenv_function;
00637        zend_resolve_path = utility_functions->resolve_path_function;
00638 
00639        zend_compile_file = compile_file;
00640        zend_compile_string = compile_string;
00641        zend_execute = execute;
00642        zend_execute_internal = NULL;
00643        zend_throw_exception_hook = NULL;
00644 
00645        zend_init_opcodes_handlers();
00646 
00647        /* set up version */
00648        zend_version_info = strdup(ZEND_CORE_VERSION_INFO);
00649        zend_version_info_length = sizeof(ZEND_CORE_VERSION_INFO) - 1;
00650 
00651        GLOBAL_FUNCTION_TABLE = (HashTable *) malloc(sizeof(HashTable));
00652        GLOBAL_CLASS_TABLE = (HashTable *) malloc(sizeof(HashTable));
00653        GLOBAL_AUTO_GLOBALS_TABLE = (HashTable *) malloc(sizeof(HashTable));
00654        GLOBAL_CONSTANTS_TABLE = (HashTable *) malloc(sizeof(HashTable));
00655 
00656        zend_hash_init_ex(GLOBAL_FUNCTION_TABLE, 100, NULL, ZEND_FUNCTION_DTOR, 1, 0);
00657        zend_hash_init_ex(GLOBAL_CLASS_TABLE, 10, NULL, ZEND_CLASS_DTOR, 1, 0);
00658        zend_hash_init_ex(GLOBAL_AUTO_GLOBALS_TABLE, 8, NULL, (dtor_func_t) zend_auto_global_dtor, 1, 0);
00659        zend_hash_init_ex(GLOBAL_CONSTANTS_TABLE, 20, NULL, ZEND_CONSTANT_DTOR, 1, 0);
00660 
00661        zend_hash_init_ex(&module_registry, 50, NULL, ZEND_MODULE_DTOR, 1, 0);
00662        zend_init_rsrc_list_dtors();
00663 
00664        /* This zval can be used to initialize allocate zval's to an uninit'ed value */
00665        Z_UNSET_ISREF(zval_used_for_init);
00666        Z_SET_REFCOUNT(zval_used_for_init, 1);
00667        Z_TYPE(zval_used_for_init) = IS_NULL;
00668 
00669 #ifdef ZTS
00670        ts_allocate_id(&compiler_globals_id, sizeof(zend_compiler_globals), (ts_allocate_ctor) compiler_globals_ctor, (ts_allocate_dtor) compiler_globals_dtor);
00671        ts_allocate_id(&executor_globals_id, sizeof(zend_executor_globals), (ts_allocate_ctor) executor_globals_ctor, (ts_allocate_dtor) executor_globals_dtor);
00672        ts_allocate_id(&language_scanner_globals_id, sizeof(zend_php_scanner_globals), (ts_allocate_ctor) php_scanner_globals_ctor, NULL);
00673        ts_allocate_id(&ini_scanner_globals_id, sizeof(zend_ini_scanner_globals), (ts_allocate_ctor) ini_scanner_globals_ctor, NULL);
00674        compiler_globals = ts_resource(compiler_globals_id);
00675        executor_globals = ts_resource(executor_globals_id);
00676 
00677        compiler_globals_dtor(compiler_globals TSRMLS_CC);
00678        compiler_globals->in_compilation = 0;
00679        compiler_globals->function_table = (HashTable *) malloc(sizeof(HashTable));
00680        compiler_globals->class_table = (HashTable *) malloc(sizeof(HashTable));
00681 
00682        *compiler_globals->function_table = *GLOBAL_FUNCTION_TABLE;
00683        *compiler_globals->class_table = *GLOBAL_CLASS_TABLE;
00684        compiler_globals->auto_globals = GLOBAL_AUTO_GLOBALS_TABLE;
00685 
00686        zend_hash_destroy(executor_globals->zend_constants);
00687        *executor_globals->zend_constants = *GLOBAL_CONSTANTS_TABLE;
00688 #else
00689        ini_scanner_globals_ctor(&ini_scanner_globals TSRMLS_CC);
00690        php_scanner_globals_ctor(&language_scanner_globals TSRMLS_CC);
00691        zend_set_default_compile_time_values(TSRMLS_C);
00692        EG(user_error_handler) = NULL;
00693        EG(user_exception_handler) = NULL;
00694 #endif
00695 
00696        zend_startup_builtin_functions(TSRMLS_C);
00697        zend_register_standard_constants(TSRMLS_C);
00698        zend_register_auto_global("GLOBALS", sizeof("GLOBALS") - 1, NULL TSRMLS_CC);
00699 
00700 #ifndef ZTS
00701        zend_init_rsrc_plist(TSRMLS_C);
00702        zend_init_exception_op(TSRMLS_C);
00703 #endif
00704 
00705        zend_ini_startup(TSRMLS_C);
00706 
00707 #ifdef ZTS
00708        tsrm_set_new_thread_end_handler(zend_new_thread_end_handler);
00709 #endif
00710 
00711        return SUCCESS;
00712 }
00713 /* }}} */
00714 
00715 void zend_register_standard_ini_entries(TSRMLS_D) /* {{{ */
00716 {
00717        int module_number = 0;
00718 
00719        REGISTER_INI_ENTRIES();
00720 }
00721 /* }}} */
00722 
00723 /* Unlink the global (r/o) copies of the class, function and constant tables,
00724  * and use a fresh r/w copy for the startup thread
00725  */
00726 void zend_post_startup(TSRMLS_D) /* {{{ */
00727 {
00728 #ifdef ZTS
00729        zend_compiler_globals *compiler_globals = ts_resource(compiler_globals_id);
00730        zend_executor_globals *executor_globals = ts_resource(executor_globals_id);
00731 
00732        *GLOBAL_FUNCTION_TABLE = *compiler_globals->function_table;
00733        *GLOBAL_CLASS_TABLE = *compiler_globals->class_table;
00734        *GLOBAL_CONSTANTS_TABLE = *executor_globals->zend_constants;
00735 
00736        asp_tags_default = CG(asp_tags);
00737        short_tags_default = CG(short_tags);
00738        ct_pass_ref_default = CG(allow_call_time_pass_reference);
00739        compiler_options_default = CG(compiler_options);
00740 
00741        zend_destroy_rsrc_list(&EG(persistent_list) TSRMLS_CC);
00742        free(compiler_globals->function_table);
00743        free(compiler_globals->class_table);
00744        compiler_globals_ctor(compiler_globals, tsrm_ls);
00745        free(EG(zend_constants));
00746        executor_globals_ctor(executor_globals, tsrm_ls);
00747        global_persistent_list = &EG(persistent_list);
00748        zend_copy_ini_directives(TSRMLS_C);
00749 #endif
00750 }
00751 /* }}} */
00752 
00753 void zend_shutdown(TSRMLS_D) /* {{{ */
00754 {
00755 #ifdef ZEND_WIN32
00756        zend_shutdown_timeout_thread();
00757 #endif
00758        zend_destroy_rsrc_list(&EG(persistent_list) TSRMLS_CC);
00759        zend_hash_graceful_reverse_destroy(&module_registry);
00760 
00761        zend_hash_destroy(GLOBAL_FUNCTION_TABLE);
00762        zend_hash_destroy(GLOBAL_CLASS_TABLE);
00763 
00764        zend_hash_destroy(GLOBAL_AUTO_GLOBALS_TABLE);
00765        free(GLOBAL_AUTO_GLOBALS_TABLE);
00766 
00767        zend_shutdown_extensions(TSRMLS_C);
00768        free(zend_version_info);
00769 
00770        free(GLOBAL_FUNCTION_TABLE);
00771        free(GLOBAL_CLASS_TABLE);
00772 
00773        zend_hash_destroy(GLOBAL_CONSTANTS_TABLE);
00774        free(GLOBAL_CONSTANTS_TABLE);
00775        zend_shutdown_strtod();
00776 
00777 #ifdef ZTS
00778        GLOBAL_FUNCTION_TABLE = NULL;
00779        GLOBAL_CLASS_TABLE = NULL;
00780        GLOBAL_AUTO_GLOBALS_TABLE = NULL;
00781        GLOBAL_CONSTANTS_TABLE = NULL;
00782 #endif
00783        zend_destroy_rsrc_list_dtors();
00784 }
00785 /* }}} */
00786 
00787 void zend_set_utility_values(zend_utility_values *utility_values) /* {{{ */
00788 {
00789        zend_uv = *utility_values;
00790        zend_uv.import_use_extension_length = strlen(zend_uv.import_use_extension);
00791 }
00792 /* }}} */
00793 
00794 /* this should be compatible with the standard zenderror */
00795 void zenderror(const char *error) /* {{{ */
00796 {
00797        zend_error(E_PARSE, "%s", error);
00798 }
00799 /* }}} */
00800 
00801 BEGIN_EXTERN_C()
00802 ZEND_API void _zend_bailout(char *filename, uint lineno) /* {{{ */
00803 {
00804        TSRMLS_FETCH();
00805 
00806        if (!EG(bailout)) {
00807               zend_output_debug_string(1, "%s(%d) : Bailed out without a bailout address!", filename, lineno);
00808               exit(-1);
00809        }
00810        CG(unclean_shutdown) = 1;
00811        CG(active_class_entry) = NULL;
00812        CG(in_compilation) = EG(in_execution) = 0;
00813        EG(current_execute_data) = NULL;
00814        LONGJMP(*EG(bailout), FAILURE);
00815 }
00816 /* }}} */
00817 END_EXTERN_C()
00818 
00819 void zend_append_version_info(const zend_extension *extension) /* {{{ */
00820 {
00821        char *new_info;
00822        uint new_info_length;
00823 
00824        new_info_length = sizeof("    with  v, , by \n")
00825                                           + strlen(extension->name)
00826                                           + strlen(extension->version)
00827                                           + strlen(extension->copyright)
00828                                           + strlen(extension->author);
00829 
00830        new_info = (char *) malloc(new_info_length + 1);
00831 
00832        snprintf(new_info, new_info_length, "    with %s v%s, %s, by %s\n", extension->name, extension->version, extension->copyright, extension->author);
00833 
00834        zend_version_info = (char *) realloc(zend_version_info, zend_version_info_length+new_info_length + 1);
00835        strncat(zend_version_info, new_info, new_info_length);
00836        zend_version_info_length += new_info_length;
00837        free(new_info);
00838 }
00839 /* }}} */
00840 
00841 ZEND_API char *get_zend_version(void) /* {{{ */
00842 {
00843        return zend_version_info;
00844 }
00845 /* }}} */
00846 
00847 void zend_activate(TSRMLS_D) /* {{{ */
00848 {
00849        gc_reset(TSRMLS_C);
00850        init_compiler(TSRMLS_C);
00851        init_executor(TSRMLS_C);
00852        startup_scanner(TSRMLS_C);
00853 }
00854 /* }}} */
00855 
00856 void zend_activate_modules(TSRMLS_D) /* {{{ */
00857 {
00858        zend_hash_apply(&module_registry, (apply_func_t) module_registry_request_startup TSRMLS_CC);
00859 }
00860 /* }}} */
00861 
00862 void zend_deactivate_modules(TSRMLS_D) /* {{{ */
00863 {
00864        EG(opline_ptr) = NULL; /* we're no longer executing anything */
00865 
00866        zend_try {
00867               zend_hash_reverse_apply(&module_registry, (apply_func_t) module_registry_cleanup TSRMLS_CC);
00868        } zend_end_try();
00869 }
00870 /* }}} */
00871 
00872 void zend_call_destructors(TSRMLS_D) /* {{{ */
00873 {
00874        zend_try {
00875               shutdown_destructors(TSRMLS_C);
00876        } zend_end_try();
00877 }
00878 /* }}} */
00879 
00880 void zend_deactivate(TSRMLS_D) /* {{{ */
00881 {
00882        /* we're no longer executing anything */
00883        EG(opline_ptr) = NULL;
00884        EG(active_symbol_table) = NULL;
00885 
00886        zend_try {
00887               shutdown_scanner(TSRMLS_C);
00888        } zend_end_try();
00889 
00890        /* shutdown_executor() takes care of its own bailout handling */
00891        shutdown_executor(TSRMLS_C);
00892 
00893        zend_try {
00894               shutdown_compiler(TSRMLS_C);
00895        } zend_end_try();
00896 
00897        zend_destroy_rsrc_list(&EG(regular_list) TSRMLS_CC);
00898 
00899 #ifdef ZEND_DEBUG
00900        if (GC_G(gc_enabled) && !CG(unclean_shutdown)) {
00901               gc_collect_cycles(TSRMLS_C);
00902        }
00903 #endif
00904 
00905 #if GC_BENCH
00906        fprintf(stderr, "GC Statistics\n");
00907        fprintf(stderr, "-------------\n");
00908        fprintf(stderr, "Runs:               %d\n", GC_G(gc_runs));
00909        fprintf(stderr, "Collected:          %d\n", GC_G(collected));
00910        fprintf(stderr, "Root buffer length: %d\n", GC_G(root_buf_length));
00911        fprintf(stderr, "Root buffer peak:   %d\n\n", GC_G(root_buf_peak));
00912        fprintf(stderr, "      Possible            Remove from  Marked\n");
00913        fprintf(stderr, "        Root    Buffered     buffer     grey\n");
00914        fprintf(stderr, "      --------  --------  -----------  ------\n");
00915        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));
00916        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));
00917 #endif
00918 
00919        zend_try {
00920               zend_ini_deactivate(TSRMLS_C);
00921        } zend_end_try();
00922 }
00923 /* }}} */
00924 
00925 static int exec_done_cb(zend_module_entry *module TSRMLS_DC) /* {{{ */
00926 {
00927        if (module->post_deactivate_func) {
00928               module->post_deactivate_func();
00929        }
00930        return 0;
00931 }
00932 /* }}} */
00933 
00934 void zend_post_deactivate_modules(TSRMLS_D) /* {{{ */
00935 {
00936        zend_hash_apply(&module_registry, (apply_func_t) exec_done_cb TSRMLS_CC);
00937        zend_hash_reverse_apply(&module_registry, (apply_func_t) module_registry_unload_temp TSRMLS_CC);
00938 }
00939 /* }}} */
00940 
00941 BEGIN_EXTERN_C()
00942 ZEND_API void zend_message_dispatcher(long message, void *data TSRMLS_DC) /* {{{ */
00943 {
00944        if (zend_message_dispatcher_p) {
00945               zend_message_dispatcher_p(message, data TSRMLS_CC);
00946        }
00947 }
00948 /* }}} */
00949 END_EXTERN_C()
00950 
00951 ZEND_API int zend_get_configuration_directive(const char *name, uint name_length, zval *contents) /* {{{ */
00952 {
00953        if (zend_get_configuration_directive_p) {
00954               return zend_get_configuration_directive_p(name, name_length, contents);
00955        } else {
00956               return FAILURE;
00957        }
00958 }
00959 /* }}} */
00960 
00961 #define SAVE_STACK(stack) do { \
00962               if (CG(stack).top) { \
00963                      memcpy(&stack, &CG(stack), sizeof(zend_stack)); \
00964                      CG(stack).top = CG(stack).max = 0; \
00965                      CG(stack).elements = NULL; \
00966               } else { \
00967                      stack.top = 0; \
00968               } \
00969        } while (0)
00970 
00971 #define RESTORE_STACK(stack) do { \
00972               if (stack.top) { \
00973                      zend_stack_destroy(&CG(stack)); \
00974                      memcpy(&CG(stack), &stack, sizeof(zend_stack)); \
00975               } \
00976        } while (0)
00977 
00978 ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
00979 {
00980        va_list args;
00981        va_list usr_copy;
00982        zval ***params;
00983        zval *retval;
00984        zval *z_error_type, *z_error_message, *z_error_filename, *z_error_lineno, *z_context;
00985        char *error_filename;
00986        uint error_lineno;
00987        zval *orig_user_error_handler;
00988        zend_bool in_compilation;
00989        zend_class_entry *saved_class_entry;
00990        zend_stack bp_stack;
00991        zend_stack function_call_stack;
00992        zend_stack switch_cond_stack;
00993        zend_stack foreach_copy_stack;
00994        zend_stack object_stack;
00995        zend_stack declare_stack;
00996        zend_stack list_stack;
00997        zend_stack labels_stack;
00998        TSRMLS_FETCH();
00999 
01000        /* Obtain relevant filename and lineno */
01001        switch (type) {
01002               case E_CORE_ERROR:
01003               case E_CORE_WARNING:
01004                      error_filename = NULL;
01005                      error_lineno = 0;
01006                      break;
01007               case E_PARSE:
01008               case E_COMPILE_ERROR:
01009               case E_COMPILE_WARNING:
01010               case E_ERROR:
01011               case E_NOTICE:
01012               case E_STRICT:
01013               case E_DEPRECATED:
01014               case E_WARNING:
01015               case E_USER_ERROR:
01016               case E_USER_WARNING:
01017               case E_USER_NOTICE:
01018               case E_USER_DEPRECATED:
01019               case E_RECOVERABLE_ERROR:
01020                      if (zend_is_compiling(TSRMLS_C)) {
01021                             error_filename = zend_get_compiled_filename(TSRMLS_C);
01022                             error_lineno = zend_get_compiled_lineno(TSRMLS_C);
01023                      } else if (zend_is_executing(TSRMLS_C)) {
01024                             error_filename = zend_get_executed_filename(TSRMLS_C);
01025                             error_lineno = zend_get_executed_lineno(TSRMLS_C);
01026                      } else {
01027                             error_filename = NULL;
01028                             error_lineno = 0;
01029                      }
01030                      break;
01031               default:
01032                      error_filename = NULL;
01033                      error_lineno = 0;
01034                      break;
01035        }
01036        if (!error_filename) {
01037               error_filename = "Unknown";
01038        }
01039 
01040        va_start(args, format);
01041 
01042        /* if we don't have a user defined error handler */
01043        if (!EG(user_error_handler)
01044               || !(EG(user_error_handler_error_reporting) & type)
01045               || EG(error_handling) != EH_NORMAL) {
01046               zend_error_cb(type, error_filename, error_lineno, format, args);
01047        } else switch (type) {
01048               case E_ERROR:
01049               case E_PARSE:
01050               case E_CORE_ERROR:
01051               case E_CORE_WARNING:
01052               case E_COMPILE_ERROR:
01053               case E_COMPILE_WARNING:
01054                      /* The error may not be safe to handle in user-space */
01055                      zend_error_cb(type, error_filename, error_lineno, format, args);
01056                      break;
01057               default:
01058                      /* Handle the error in user space */
01059                      ALLOC_INIT_ZVAL(z_error_message);
01060                      ALLOC_INIT_ZVAL(z_error_type);
01061                      ALLOC_INIT_ZVAL(z_error_filename);
01062                      ALLOC_INIT_ZVAL(z_error_lineno);
01063                      ALLOC_INIT_ZVAL(z_context);
01064 
01065 /* va_copy() is __va_copy() in old gcc versions.
01066  * According to the autoconf manual, using
01067  * memcpy(&dst, &src, sizeof(va_list))
01068  * gives maximum portability. */
01069 #ifndef va_copy
01070 # ifdef __va_copy
01071 #  define va_copy(dest, src)       __va_copy((dest), (src))
01072 # else
01073 #  define va_copy(dest, src)       memcpy(&(dest), &(src), sizeof(va_list))
01074 # endif
01075 #endif
01076                      va_copy(usr_copy, args);
01077                      Z_STRLEN_P(z_error_message) = zend_vspprintf(&Z_STRVAL_P(z_error_message), 0, format, usr_copy);
01078 #ifdef va_copy
01079                      va_end(usr_copy);
01080 #endif
01081                      Z_TYPE_P(z_error_message) = IS_STRING;
01082 
01083                      Z_LVAL_P(z_error_type) = type;
01084                      Z_TYPE_P(z_error_type) = IS_LONG;
01085 
01086                      if (error_filename) {
01087                             ZVAL_STRING(z_error_filename, error_filename, 1);
01088                      }
01089 
01090                      Z_LVAL_P(z_error_lineno) = error_lineno;
01091                      Z_TYPE_P(z_error_lineno) = IS_LONG;
01092 
01093                      if (!EG(active_symbol_table)) {
01094                             zend_rebuild_symbol_table(TSRMLS_C);
01095                      }
01096 
01097                      /* during shutdown the symbol table table can be still null */
01098                      if (!EG(active_symbol_table)) {
01099                             Z_TYPE_P(z_context) = IS_NULL;
01100                      } else {
01101                             Z_ARRVAL_P(z_context) = EG(active_symbol_table);
01102                             Z_TYPE_P(z_context) = IS_ARRAY;
01103                             zval_copy_ctor(z_context);
01104                      }
01105 
01106                      params = (zval ***) emalloc(sizeof(zval **)*5);
01107                      params[0] = &z_error_type;
01108                      params[1] = &z_error_message;
01109                      params[2] = &z_error_filename;
01110                      params[3] = &z_error_lineno;
01111                      params[4] = &z_context;
01112 
01113                      orig_user_error_handler = EG(user_error_handler);
01114                      EG(user_error_handler) = NULL;
01115 
01116                      /* User error handler may include() additinal PHP files.
01117                       * If an error was generated during comilation PHP will compile
01118                       * such scripts recursivly, but some CG() variables may be
01119                       * inconsistent. */
01120 
01121                      in_compilation = zend_is_compiling(TSRMLS_C);
01122                      if (in_compilation) {
01123                             saved_class_entry = CG(active_class_entry);
01124                             CG(active_class_entry) = NULL;
01125                             SAVE_STACK(bp_stack);
01126                             SAVE_STACK(function_call_stack);
01127                             SAVE_STACK(switch_cond_stack);
01128                             SAVE_STACK(foreach_copy_stack);
01129                             SAVE_STACK(object_stack);
01130                             SAVE_STACK(declare_stack);
01131                             SAVE_STACK(list_stack);
01132                             SAVE_STACK(labels_stack);
01133                      }
01134 
01135                      if (call_user_function_ex(CG(function_table), NULL, orig_user_error_handler, &retval, 5, params, 1, NULL TSRMLS_CC) == SUCCESS) {
01136                             if (retval) {
01137                                    if (Z_TYPE_P(retval) == IS_BOOL && Z_LVAL_P(retval) == 0) {
01138                                           zend_error_cb(type, error_filename, error_lineno, format, args);
01139                                    }
01140                                    zval_ptr_dtor(&retval);
01141                             }
01142                      } else if (!EG(exception)) {
01143                             /* The user error handler failed, use built-in error handler */
01144                             zend_error_cb(type, error_filename, error_lineno, format, args);
01145                      }
01146 
01147                      if (in_compilation) {
01148                             CG(active_class_entry) = saved_class_entry;
01149                             RESTORE_STACK(bp_stack);
01150                             RESTORE_STACK(function_call_stack);
01151                             RESTORE_STACK(switch_cond_stack);
01152                             RESTORE_STACK(foreach_copy_stack);
01153                             RESTORE_STACK(object_stack);
01154                             RESTORE_STACK(declare_stack);
01155                             RESTORE_STACK(list_stack);
01156                             RESTORE_STACK(labels_stack);
01157                      }
01158 
01159                      if (!EG(user_error_handler)) {
01160                             EG(user_error_handler) = orig_user_error_handler;
01161                      }
01162                      else {
01163                             zval_ptr_dtor(&orig_user_error_handler);
01164                      }
01165 
01166                      efree(params);
01167                      zval_ptr_dtor(&z_error_message);
01168                      zval_ptr_dtor(&z_error_type);
01169                      zval_ptr_dtor(&z_error_filename);
01170                      zval_ptr_dtor(&z_error_lineno);
01171                      zval_ptr_dtor(&z_context);
01172                      break;
01173        }
01174 
01175        va_end(args);
01176 
01177        if (type == E_PARSE) {
01178               EG(exit_status) = 255;
01179               zend_init_compiler_data_structures(TSRMLS_C);
01180        }
01181 }
01182 /* }}} */
01183 
01184 #if defined(__GNUC__) && __GNUC__ >= 3 && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) && !defined(__osf__)
01185 void zend_error_noreturn(int type, const char *format, ...) __attribute__ ((alias("zend_error"),noreturn));
01186 #endif
01187 
01188 ZEND_API void zend_output_debug_string(zend_bool trigger_break, const char *format, ...) /* {{{ */
01189 {
01190 #if ZEND_DEBUG
01191        va_list args;
01192 
01193        va_start(args, format);
01194 #      ifdef ZEND_WIN32
01195        {
01196               char output_buf[1024];
01197 
01198               vsnprintf(output_buf, 1024, format, args);
01199               OutputDebugString(output_buf);
01200               OutputDebugString("\n");
01201               if (trigger_break && IsDebuggerPresent()) {
01202                      DebugBreak();
01203               }
01204        }
01205 #      else
01206        vfprintf(stderr, format, args);
01207        fprintf(stderr, "\n");
01208 #      endif
01209        va_end(args);
01210 #endif
01211 }
01212 /* }}} */
01213 
01214 ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval **retval, int file_count, ...) /* {{{ */
01215 {
01216        va_list files;
01217        int i;
01218        zend_file_handle *file_handle;
01219        zend_op_array *orig_op_array = EG(active_op_array);
01220        zval **orig_retval_ptr_ptr = EG(return_value_ptr_ptr);
01221 
01222        va_start(files, file_count);
01223        for (i = 0; i < file_count; i++) {
01224               file_handle = va_arg(files, zend_file_handle *);
01225               if (!file_handle) {
01226                      continue;
01227               }
01228               EG(active_op_array) = zend_compile_file(file_handle, type TSRMLS_CC);
01229               if (file_handle->opened_path) {
01230                      int dummy = 1;
01231                      zend_hash_add(&EG(included_files), file_handle->opened_path, strlen(file_handle->opened_path) + 1, (void *)&dummy, sizeof(int), NULL);
01232               }
01233               zend_destroy_file_handle(file_handle TSRMLS_CC);
01234               if (EG(active_op_array)) {
01235                      EG(return_value_ptr_ptr) = retval ? retval : NULL;
01236                      zend_execute(EG(active_op_array) TSRMLS_CC);
01237                      zend_exception_restore(TSRMLS_C);
01238                      if (EG(exception)) {
01239                             if (EG(user_exception_handler)) {
01240                                    zval *orig_user_exception_handler;
01241                                    zval **params[1], *retval2, *old_exception;
01242                                    old_exception = EG(exception);
01243                                    EG(exception) = NULL;
01244                                    params[0] = &old_exception;
01245                                    orig_user_exception_handler = EG(user_exception_handler);
01246                                    if (call_user_function_ex(CG(function_table), NULL, orig_user_exception_handler, &retval2, 1, params, 1, NULL TSRMLS_CC) == SUCCESS) {
01247                                           if (retval2 != NULL) {
01248                                                  zval_ptr_dtor(&retval2);
01249                                           }
01250                                           if (EG(exception)) {
01251                                                  zval_ptr_dtor(&EG(exception));
01252                                                  EG(exception) = NULL;
01253                                           }
01254                                           zval_ptr_dtor(&old_exception);
01255                                    } else {
01256                                           EG(exception) = old_exception;
01257                                           zend_exception_error(EG(exception), E_ERROR TSRMLS_CC);
01258                                    }
01259                             } else {
01260                                    zend_exception_error(EG(exception), E_ERROR TSRMLS_CC);
01261                             }
01262                      }
01263                      destroy_op_array(EG(active_op_array) TSRMLS_CC);
01264                      efree(EG(active_op_array));
01265               } else if (type==ZEND_REQUIRE) {
01266                      va_end(files);
01267                      EG(active_op_array) = orig_op_array;
01268                      EG(return_value_ptr_ptr) = orig_retval_ptr_ptr;
01269                      return FAILURE;
01270               }
01271        }
01272        va_end(files);
01273        EG(active_op_array) = orig_op_array;
01274        EG(return_value_ptr_ptr) = orig_retval_ptr_ptr;
01275 
01276        return SUCCESS;
01277 }
01278 /* }}} */
01279 
01280 #define COMPILED_STRING_DESCRIPTION_FORMAT "%s(%d) : %s"
01281 
01282 ZEND_API char *zend_make_compiled_string_description(const char *name TSRMLS_DC) /* {{{ */
01283 {
01284        char *cur_filename;
01285        int cur_lineno;
01286        char *compiled_string_description;
01287 
01288        if (zend_is_compiling(TSRMLS_C)) {
01289               cur_filename = zend_get_compiled_filename(TSRMLS_C);
01290               cur_lineno = zend_get_compiled_lineno(TSRMLS_C);
01291        } else if (zend_is_executing(TSRMLS_C)) {
01292               cur_filename = zend_get_executed_filename(TSRMLS_C);
01293               cur_lineno = zend_get_executed_lineno(TSRMLS_C);
01294        } else {
01295               cur_filename = "Unknown";
01296               cur_lineno = 0;
01297        }
01298 
01299        zend_spprintf(&compiled_string_description, 0, COMPILED_STRING_DESCRIPTION_FORMAT, cur_filename, cur_lineno, name);
01300        return compiled_string_description;
01301 }
01302 /* }}} */
01303 
01304 void free_estring(char **str_p) /* {{{ */
01305 {
01306        efree(*str_p);
01307 }
01308 /* }}} */
01309 
01310 /*
01311  * Local variables:
01312  * tab-width: 4
01313  * c-basic-offset: 4
01314  * indent-tabs-mode: t
01315  * End:
01316  */