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