File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / Zend / zend.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Oct 14 08:02:46 2013 UTC (10 years, 8 months ago) by misho
Branches: php, MAIN
CVS tags: v5_4_29p0, v5_4_20p0, v5_4_20, HEAD
v 5.4.20

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>