zend.c revision 92dd5e61
1573b4602SAndi Gutmans/*
2573b4602SAndi Gutmans   +----------------------------------------------------------------------+
3573b4602SAndi Gutmans   | Zend Engine                                                          |
4573b4602SAndi Gutmans   +----------------------------------------------------------------------+
562dc854bSSebastian Bergmann   | Copyright (c) 1998-2002 Zend Technologies Ltd. (http://www.zend.com) |
6573b4602SAndi Gutmans   +----------------------------------------------------------------------+
7d863d52aSSebastian Bergmann   | This source file is subject to version 2.00 of the Zend license,     |
8b5b11177SZeev Suraski   | that is bundled with this package in the file LICENSE, and is        |
9b5b11177SZeev Suraski   | available at through the world-wide-web at                           |
10d863d52aSSebastian Bergmann   | http://www.zend.com/license/2_00.txt.                                |
11b5b11177SZeev Suraski   | If you did not receive a copy of the Zend license and are unable to  |
12b5b11177SZeev Suraski   | obtain it through the world-wide-web, please send a note to          |
13b5b11177SZeev Suraski   | license@zend.com so we can mail you a copy immediately.              |
14573b4602SAndi Gutmans   +----------------------------------------------------------------------+
15573b4602SAndi Gutmans   | Authors: Andi Gutmans <andi@zend.com>                                |
16573b4602SAndi Gutmans   |          Zeev Suraski <zeev@zend.com>                                |
17573b4602SAndi Gutmans   +----------------------------------------------------------------------+
18573b4602SAndi Gutmans*/
19573b4602SAndi Gutmans
20a6043d3eSRasmus Lerdorf
21573b4602SAndi Gutmans#include "zend.h"
22573b4602SAndi Gutmans#include "zend_extensions.h"
237080fa5bSAndi Gutmans#include "zend_modules.h"
24573b4602SAndi Gutmans#include "zend_constants.h"
25573b4602SAndi Gutmans#include "zend_list.h"
26da9faa2cSZeev Suraski#include "zend_API.h"
2713d840bcSZeev Suraski#include "zend_builtin_functions.h"
2854d53055SZeev Suraski#include "zend_ini.h"
29573b4602SAndi Gutmans
307a87fcbbSZeev Suraski#ifdef ZTS
31ce98c73fSAndi Gutmans#	define GLOBAL_FUNCTION_TABLE	&global_main_class.function_table
32ce98c73fSAndi Gutmans#	define GLOBAL_CLASS_TABLE		&global_main_class.class_table
33ce98c73fSAndi Gutmans#	define GLOBAL_CONSTANTS_TABLE	&global_main_class.constants_table
349d11db12SAndi Gutmans#	define GLOBAL_AUTO_GLOBALS_TABLE	global_auto_globals_table
357a87fcbbSZeev Suraski#else
367a87fcbbSZeev Suraski#	define GLOBAL_FUNCTION_TABLE	CG(function_table)
377a87fcbbSZeev Suraski#	define GLOBAL_CLASS_TABLE		CG(class_table)
38fec59d3bSAndi Gutmans#	define GLOBAL_CONSTANTS_TABLE	CG(zend_constants)
399d11db12SAndi Gutmans#	define GLOBAL_AUTO_GLOBALS_TABLE	CG(auto_globals)
407a87fcbbSZeev Suraski#endif
417a87fcbbSZeev Suraski
42f34b9d41SZeev Suraski#if defined(ZEND_WIN32) && ZEND_DEBUG
432ffe85ddSZeev SuraskiBOOL WINAPI IsDebuggerPresent(VOID);
442ffe85ddSZeev Suraski#endif
452ffe85ddSZeev Suraski
46573b4602SAndi Gutmans/* true multithread-shared globals */
4792dd5e61SStanislav MalyshevZEND_API zend_class_entry *zend_standard_class_def = NULL;
48573b4602SAndi GutmansZEND_API int (*zend_printf)(const char *format, ...);
495dba4774SZeev SuraskiZEND_API zend_write_func_t zend_write;
505463dd5bSAndi GutmansZEND_API FILE *(*zend_fopen)(const char *filename, char **opened_path);
5193536507SStig S. BakkenZEND_API void (*zend_block_interruptions)(void);
5293536507SStig S. BakkenZEND_API void (*zend_unblock_interruptions)(void);
53f1a2ee55SAndi GutmansZEND_API void (*zend_ticks_function)(int ticks);
54536221beSStanislav MalyshevZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
55536221beSStanislav Malyshev
5656251a72SZeev Suraskistatic void (*zend_message_dispatcher_p)(long message, void *data);
57903018efSZeev Suraskistatic int (*zend_get_configuration_directive_p)(char *name, uint name_length, zval *contents);
58d035af4aSZeev Suraski
5967f69743SZeev Suraski
607a87fcbbSZeev Suraski#ifdef ZTS
61e06a1ed2SZeev SuraskiZEND_API int compiler_globals_id;
62e06a1ed2SZeev SuraskiZEND_API int executor_globals_id;
635864b57eSZeev SuraskiZEND_API int alloc_globals_id;
64ce98c73fSAndi Gutmanszend_class_entry global_main_class;
659d11db12SAndi GutmansHashTable *global_auto_globals_table;
667a87fcbbSZeev Suraski#endif
67573b4602SAndi Gutmans
68573b4602SAndi Gutmanszend_utility_values zend_uv;
69573b4602SAndi Gutmans
705ba5f00fSZeev SuraskiZEND_API zval zval_used_for_init; /* True global variable */
71213d0e2fSAndi Gutmans
72573b4602SAndi Gutmans/* version information */
73573b4602SAndi Gutmansstatic char *zend_version_info;
74573b4602SAndi Gutmansstatic uint zend_version_info_length;
7562dc854bSSebastian Bergmann#define ZEND_CORE_VERSION_INFO	"Zend Engine v" ZEND_VERSION ", Copyright (c) 1998-2002 Zend Technologies\n"
76573b4602SAndi Gutmans
77573b4602SAndi Gutmans
7880bab9d9SAndrei Zmievski#define PRINT_ZVAL_INDENT 4
79573b4602SAndi Gutmans
80573b4602SAndi Gutmansstatic void print_hash(HashTable *ht, int indent)
81573b4602SAndi Gutmans{
82573b4602SAndi Gutmans	zval **tmp;
83573b4602SAndi Gutmans	char *string_key;
8463873abaSStanislav Malyshev	HashPosition iterator;
854757104eSZeev Suraski	ulong num_key;
864757104eSZeev Suraski	uint str_len;
87573b4602SAndi Gutmans	int i;
88573b4602SAndi Gutmans
89573b4602SAndi Gutmans	for (i=0; i<indent; i++) {
90573b4602SAndi Gutmans		ZEND_PUTS(" ");
91573b4602SAndi Gutmans	}
92573b4602SAndi Gutmans	ZEND_PUTS("(\n");
9380bab9d9SAndrei Zmievski	indent += PRINT_ZVAL_INDENT;
9463873abaSStanislav Malyshev	zend_hash_internal_pointer_reset_ex(ht, &iterator);
9563873abaSStanislav Malyshev	while (zend_hash_get_current_data_ex(ht, (void **) &tmp, &iterator) == SUCCESS) {
96573b4602SAndi Gutmans		for (i=0; i<indent; i++) {
97573b4602SAndi Gutmans			ZEND_PUTS(" ");
98573b4602SAndi Gutmans		}
99573b4602SAndi Gutmans		ZEND_PUTS("[");
10036eaad25SZeev Suraski		switch (zend_hash_get_current_key_ex(ht, &string_key, &str_len, &num_key, 0, &iterator)) {
101573b4602SAndi Gutmans			case HASH_KEY_IS_STRING:
102573b4602SAndi Gutmans				ZEND_PUTS(string_key);
103573b4602SAndi Gutmans				break;
104573b4602SAndi Gutmans			case HASH_KEY_IS_LONG:
1054f6c95d1SZeev Suraski				zend_printf("%ld", num_key);
106573b4602SAndi Gutmans				break;
107573b4602SAndi Gutmans		}
108573b4602SAndi Gutmans		ZEND_PUTS("] => ");
10980bab9d9SAndrei Zmievski		zend_print_zval_r(*tmp, indent+PRINT_ZVAL_INDENT);
110573b4602SAndi Gutmans		ZEND_PUTS("\n");
11163873abaSStanislav Malyshev		zend_hash_move_forward_ex(ht, &iterator);
112573b4602SAndi Gutmans	}
11380bab9d9SAndrei Zmievski	indent -= PRINT_ZVAL_INDENT;
114573b4602SAndi Gutmans	for (i=0; i<indent; i++) {
115573b4602SAndi Gutmans		ZEND_PUTS(" ");
116573b4602SAndi Gutmans	}
117573b4602SAndi Gutmans	ZEND_PUTS(")\n");
118573b4602SAndi Gutmans}
119573b4602SAndi Gutmans
1207a87fcbbSZeev Suraski
121da9faa2cSZeev SuraskiZEND_API void zend_make_printable_zval(zval *expr, zval *expr_copy, int *use_copy)
122573b4602SAndi Gutmans{
123da9faa2cSZeev Suraski	if (expr->type==IS_STRING) {
124da9faa2cSZeev Suraski		*use_copy = 0;
125da9faa2cSZeev Suraski		return;
126da9faa2cSZeev Suraski	}
127da9faa2cSZeev Suraski	switch (expr->type) {
128bdefd5daSAndi Gutmans		case IS_NULL:
129f2d703e9SZeev Suraski			expr_copy->value.str.len = 0;
130f2d703e9SZeev Suraski			expr_copy->value.str.val = empty_string;
1318c4ab98eSThies C. Arntzen			break;
132da9faa2cSZeev Suraski		case IS_BOOL:
13391d7ba76SAndi Gutmans			if (expr->value.lval) {
13491d7ba76SAndi Gutmans				expr_copy->value.str.len = 1;
13591d7ba76SAndi Gutmans				expr_copy->value.str.val = estrndup("1", 1);
13691d7ba76SAndi Gutmans			} else {
13791d7ba76SAndi Gutmans				expr_copy->value.str.len = 0;
13891d7ba76SAndi Gutmans				expr_copy->value.str.val = empty_string;
13991d7ba76SAndi Gutmans			}
140da9faa2cSZeev Suraski			break;
141da9faa2cSZeev Suraski		case IS_RESOURCE:
142da9faa2cSZeev Suraski			expr_copy->value.str.val = (char *) emalloc(sizeof("Resource id #")-1 + MAX_LENGTH_OF_LONG);
143da9faa2cSZeev Suraski			expr_copy->value.str.len = sprintf(expr_copy->value.str.val, "Resource id #%ld", expr->value.lval);
144da9faa2cSZeev Suraski			break;
145da9faa2cSZeev Suraski		case IS_ARRAY:
146da9faa2cSZeev Suraski			expr_copy->value.str.len = sizeof("Array")-1;
147da9faa2cSZeev Suraski			expr_copy->value.str.val = estrndup("Array", expr_copy->value.str.len);
148da9faa2cSZeev Suraski			break;
1491b282b35SAndi Gutmans		case IS_OBJECT:
150b04acdadSAndi Gutmans			expr_copy->value.str.val = (char *) emalloc(sizeof("Object id #")-1 + MAX_LENGTH_OF_LONG);
15192dd5e61SStanislav Malyshev			expr_copy->value.str.len = sprintf(expr_copy->value.str.val, "Object id #%ld", (long)expr->value.obj.handle);
152b04acdadSAndi Gutmans#if 0
153b04acdadSAndi Gutmans			/* FIXME: This might break BC for some people */
1541b282b35SAndi Gutmans			expr_copy->value.str.len = sizeof("Object")-1;
1551b282b35SAndi Gutmans			expr_copy->value.str.val = estrndup("Object", expr_copy->value.str.len);
156b04acdadSAndi Gutmans#endif
157da9faa2cSZeev Suraski			break;
158da9faa2cSZeev Suraski		default:
159da9faa2cSZeev Suraski			*expr_copy = *expr;
160da9faa2cSZeev Suraski			zval_copy_ctor(expr_copy);
161da9faa2cSZeev Suraski			convert_to_string(expr_copy);
162da9faa2cSZeev Suraski			break;
163da9faa2cSZeev Suraski	}
164da9faa2cSZeev Suraski	expr_copy->type = IS_STRING;
165da9faa2cSZeev Suraski	*use_copy = 1;
166da9faa2cSZeev Suraski}
167da9faa2cSZeev Suraski
168da9faa2cSZeev Suraski
169da9faa2cSZeev SuraskiZEND_API int zend_print_zval(zval *expr, int indent)
170da9faa2cSZeev Suraski{
1715dba4774SZeev Suraski	return zend_print_zval_ex(zend_write, expr, indent);
1725dba4774SZeev Suraski}
1735dba4774SZeev Suraski
1745dba4774SZeev Suraski
1755dba4774SZeev SuraskiZEND_API int zend_print_zval_ex(zend_write_func_t write_func, zval *expr, int indent)
1765dba4774SZeev Suraski{
177da9faa2cSZeev Suraski	zval expr_copy;
178da9faa2cSZeev Suraski	int use_copy;
179da9faa2cSZeev Suraski
180da9faa2cSZeev Suraski	zend_make_printable_zval(expr, &expr_copy, &use_copy);
181da9faa2cSZeev Suraski	if (use_copy) {
182573b4602SAndi Gutmans		expr = &expr_copy;
183573b4602SAndi Gutmans	}
184573b4602SAndi Gutmans	if (expr->value.str.len==0) { /* optimize away empty strings */
185da9faa2cSZeev Suraski		if (use_copy) {
186da9faa2cSZeev Suraski			zval_dtor(expr);
187da9faa2cSZeev Suraski		}
188573b4602SAndi Gutmans		return 0;
189573b4602SAndi Gutmans	}
1904f6c95d1SZeev Suraski	write_func(expr->value.str.val, expr->value.str.len);
191da9faa2cSZeev Suraski	if (use_copy) {
192573b4602SAndi Gutmans		zval_dtor(expr);
193573b4602SAndi Gutmans	}
194573b4602SAndi Gutmans	return expr->value.str.len;
195573b4602SAndi Gutmans}
196573b4602SAndi Gutmans
197573b4602SAndi Gutmans
1985dba4774SZeev SuraskiZEND_API void zend_print_zval_r(zval *expr, int indent)
1995dba4774SZeev Suraski{
2005dba4774SZeev Suraski	zend_print_zval_r_ex(zend_write, expr, indent);
2015dba4774SZeev Suraski}
2025dba4774SZeev Suraski
2035dba4774SZeev Suraski
2045dba4774SZeev SuraskiZEND_API void zend_print_zval_r_ex(zend_write_func_t write_func, zval *expr, int indent)
205573b4602SAndi Gutmans{
206573b4602SAndi Gutmans	switch(expr->type) {
207573b4602SAndi Gutmans		case IS_ARRAY:
208573b4602SAndi Gutmans			ZEND_PUTS("Array\n");
2096053f2a1SZeev Suraski			if (++expr->value.ht->nApplyCount>1) {
2106053f2a1SZeev Suraski				ZEND_PUTS(" *RECURSION*");
2116053f2a1SZeev Suraski				expr->value.ht->nApplyCount=0;
2126053f2a1SZeev Suraski				return;
2136053f2a1SZeev Suraski			}
2144f6c95d1SZeev Suraski			print_hash(expr->value.ht, indent);
2156053f2a1SZeev Suraski			expr->value.ht->nApplyCount--;
216573b4602SAndi Gutmans			break;
217573b4602SAndi Gutmans		case IS_OBJECT:
218c259cb7cSAndi Gutmans			{
219c259cb7cSAndi Gutmans				zend_object *object = Z_OBJ_P(expr);
220c259cb7cSAndi Gutmans
221c259cb7cSAndi Gutmans				if (++object->properties->nApplyCount>1) {
222c259cb7cSAndi Gutmans					ZEND_PUTS(" *RECURSION*");
223c259cb7cSAndi Gutmans					object->properties->nApplyCount=0;
224c259cb7cSAndi Gutmans					return;
225c259cb7cSAndi Gutmans				}
226c259cb7cSAndi Gutmans				zend_printf("%s Object\n", object->ce->name);
227c259cb7cSAndi Gutmans				print_hash(object->properties, indent);
228c259cb7cSAndi Gutmans				object->properties->nApplyCount--;
229c259cb7cSAndi Gutmans				break;
2306053f2a1SZeev Suraski			}
231573b4602SAndi Gutmans		default:
232573b4602SAndi Gutmans			zend_print_variable(expr);
233573b4602SAndi Gutmans			break;
234573b4602SAndi Gutmans	}
235573b4602SAndi Gutmans}
236573b4602SAndi Gutmans
237573b4602SAndi Gutmans
2385463dd5bSAndi Gutmansstatic FILE *zend_fopen_wrapper(const char *filename, char **opened_path)
239573b4602SAndi Gutmans{
2405463dd5bSAndi Gutmans	if (opened_path) {
24127de5001SAndi Gutmans		*opened_path = estrdup(filename);
2425463dd5bSAndi Gutmans	}
243f311ab16SAndi Gutmans	return fopen(filename, "rb");
244573b4602SAndi Gutmans}
245573b4602SAndi Gutmans
246573b4602SAndi Gutmans
24793536507SStig S. Bakkenstatic void register_standard_class(void)
248573b4602SAndi Gutmans{
24992dd5e61SStanislav Malyshev	zend_standard_class_def = malloc(sizeof(zend_class_entry));
25092dd5e61SStanislav Malyshev
25192dd5e61SStanislav Malyshev	zend_standard_class_def->type = ZEND_INTERNAL_CLASS;
25292dd5e61SStanislav Malyshev	zend_standard_class_def->name_length = sizeof("stdClass") - 1;
25392dd5e61SStanislav Malyshev	zend_standard_class_def->name = zend_strndup("stdClass", zend_standard_class_def->name_length);
25492dd5e61SStanislav Malyshev	zend_standard_class_def->parent = NULL;
25592dd5e61SStanislav Malyshev	zend_hash_init_ex(&zend_standard_class_def->default_properties, 0, NULL, ZVAL_PTR_DTOR, 1, 0);
25692dd5e61SStanislav Malyshev	zend_hash_init_ex(&zend_standard_class_def->private_properties, 0, NULL, ZVAL_PTR_DTOR, 1, 0);
25792dd5e61SStanislav Malyshev	zend_standard_class_def->static_members = (HashTable *) malloc(sizeof(HashTable));
25892dd5e61SStanislav Malyshev	zend_hash_init_ex(zend_standard_class_def->static_members, 0, NULL, ZVAL_PTR_DTOR, 1, 0);
25992dd5e61SStanislav Malyshev	zend_hash_init_ex(&zend_standard_class_def->constants_table, 0, NULL, ZVAL_PTR_DTOR, 1, 0);
26092dd5e61SStanislav Malyshev	zend_hash_init_ex(&zend_standard_class_def->class_table, 10, NULL, ZEND_CLASS_DTOR, 1, 0);
26192dd5e61SStanislav Malyshev	zend_hash_init_ex(&zend_standard_class_def->function_table, 0, NULL, ZEND_FUNCTION_DTOR, 1, 0);
26292dd5e61SStanislav Malyshev	zend_standard_class_def->constructor = NULL;
26392dd5e61SStanislav Malyshev	zend_standard_class_def->destructor = NULL;
26492dd5e61SStanislav Malyshev	zend_standard_class_def->clone = NULL;
26592dd5e61SStanislav Malyshev	zend_standard_class_def->handle_function_call = NULL;
26692dd5e61SStanislav Malyshev	zend_standard_class_def->handle_property_get = NULL;
26792dd5e61SStanislav Malyshev	zend_standard_class_def->handle_property_set = NULL;
26892dd5e61SStanislav Malyshev	zend_standard_class_def->refcount = (int *) malloc(sizeof(int));
26992dd5e61SStanislav Malyshev	*zend_standard_class_def->refcount = 1;
27092dd5e61SStanislav Malyshev	zend_hash_add(GLOBAL_CLASS_TABLE, "stdclass", sizeof("stdclass"), &zend_standard_class_def, sizeof(zend_class_entry *), NULL);
271573b4602SAndi Gutmans}
272573b4602SAndi Gutmans
273573b4602SAndi Gutmans
274b4f3b9d3SZeev Suraskistatic void zend_set_default_compile_time_values(TSRMLS_D)
2758b794bb1SZeev Suraski{
2768b794bb1SZeev Suraski	/* default compile-time values */
2778b794bb1SZeev Suraski	CG(asp_tags) = 0;
2788b794bb1SZeev Suraski	CG(short_tags) = 1;
2798b794bb1SZeev Suraski	CG(allow_call_time_pass_reference) = 1;
2808b794bb1SZeev Suraski	CG(extended_info) = 0;
2818b794bb1SZeev Suraski}
2828b794bb1SZeev Suraski
2838b794bb1SZeev Suraski
2847a87fcbbSZeev Suraski#ifdef ZTS
2852c254ba7SZeev Suraskistatic void compiler_globals_ctor(zend_compiler_globals *compiler_globals TSRMLS_DC)
2867a87fcbbSZeev Suraski{
2877c4a0838SZeev Suraski	zend_function tmp_func;
2887c4a0838SZeev Suraski	zend_class_entry tmp_class;
2897c4a0838SZeev Suraski
2907f4909d9SThies C. Arntzen	compiler_globals->compiled_filename = NULL;
2917f4909d9SThies C. Arntzen
292ce98c73fSAndi Gutmans	compiler_globals->function_table = &compiler_globals->main_class.function_table;
2931263932aSZeev Suraski	zend_hash_init_ex(compiler_globals->function_table, 100, NULL, ZEND_FUNCTION_DTOR, 1, 0);
294ce98c73fSAndi Gutmans	zend_hash_copy(compiler_globals->function_table, GLOBAL_FUNCTION_TABLE, NULL, &tmp_func, sizeof(zend_function));
2957a87fcbbSZeev Suraski
296ce98c73fSAndi Gutmans	compiler_globals->class_table = &compiler_globals->main_class.class_table;
2971263932aSZeev Suraski	zend_hash_init_ex(compiler_globals->class_table, 10, NULL, ZEND_CLASS_DTOR, 1, 0);
298ce98c73fSAndi Gutmans	zend_hash_copy(compiler_globals->class_table, GLOBAL_CLASS_TABLE, (copy_ctor_func_t) zend_class_add_ref, &tmp_class, sizeof(zend_class_entry));
2999cf1a98dSThies C. Arntzen
300b4f3b9d3SZeev Suraski	zend_set_default_compile_time_values(TSRMLS_C);
30185b4df53SZeev Suraski
30285b4df53SZeev Suraski	CG(interactive) = 0;
3039d11db12SAndi Gutmans
3049d11db12SAndi Gutmans	compiler_globals->auto_globals = (HashTable *) malloc(sizeof(HashTable));
3059d11db12SAndi Gutmans	zend_hash_init_ex(compiler_globals->auto_globals, 8, NULL, NULL, 1, 0);
3069d11db12SAndi Gutmans	zend_hash_copy(compiler_globals->auto_globals, global_auto_globals_table, NULL, NULL, sizeof(void *) /* empty element */);
3077a87fcbbSZeev Suraski}
3087a87fcbbSZeev Suraski
3097a87fcbbSZeev Suraski
3102c254ba7SZeev Suraskistatic void compiler_globals_dtor(zend_compiler_globals *compiler_globals TSRMLS_DC)
3117a87fcbbSZeev Suraski{
312ce98c73fSAndi Gutmans	if (compiler_globals->function_table != GLOBAL_FUNCTION_TABLE) {
31374a9ed7bSZeev Suraski		zend_hash_destroy(compiler_globals->function_table);
31474a9ed7bSZeev Suraski	}
315ce98c73fSAndi Gutmans	if (compiler_globals->class_table != GLOBAL_CLASS_TABLE) {
31674a9ed7bSZeev Suraski		zend_hash_destroy(compiler_globals->class_table);
31774a9ed7bSZeev Suraski	}
3189d11db12SAndi Gutmans	if (compiler_globals->auto_globals != global_auto_globals_table) {
3199d11db12SAndi Gutmans		zend_hash_destroy(compiler_globals->auto_globals);
3209d11db12SAndi Gutmans		free(compiler_globals->auto_globals);
3219d11db12SAndi Gutmans	}
3227a87fcbbSZeev Suraski}
323a9f9ae79SZeev Suraski
324a9f9ae79SZeev Suraski
3252c254ba7SZeev Suraskistatic void executor_globals_ctor(zend_executor_globals *executor_globals TSRMLS_DC)
326a9f9ae79SZeev Suraski{
327ce98c73fSAndi Gutmans	if (GLOBAL_CONSTANTS_TABLE) {
3282c254ba7SZeev Suraski		zend_startup_constants(TSRMLS_C);
329ce98c73fSAndi Gutmans		zend_copy_constants(EG(zend_constants), GLOBAL_CONSTANTS_TABLE);
330fec59d3bSAndi Gutmans	}
3312c254ba7SZeev Suraski	zend_init_rsrc_plist(TSRMLS_C);
3320b7a9ceaSZeev Suraski	EG(lambda_count)=0;
3331f23e507SZeev Suraski	EG(user_error_handler) = NULL;
334ab30c8ccSZeev Suraski	EG(in_execution) = 0;
335a9f9ae79SZeev Suraski}
336a9f9ae79SZeev Suraski
337a9f9ae79SZeev Suraski
3382c254ba7SZeev Suraskistatic void executor_globals_dtor(zend_executor_globals *executor_globals TSRMLS_DC)
339a9f9ae79SZeev Suraski{
3402c254ba7SZeev Suraski	zend_shutdown_constants(TSRMLS_C);
3417deb44e3SZeev Suraski	zend_destroy_rsrc_list(&EG(persistent_list) TSRMLS_CC);
3422c254ba7SZeev Suraski	zend_ini_shutdown(TSRMLS_C);
343a9f9ae79SZeev Suraski}
344a9f9ae79SZeev Suraski
345a9f9ae79SZeev Suraski
346609d58a4SZeev Suraskistatic void zend_new_thread_end_handler(THREAD_T thread_id TSRMLS_DC)
347609d58a4SZeev Suraski{
348609d58a4SZeev Suraski	zend_copy_ini_directives(TSRMLS_C);
349609d58a4SZeev Suraski	zend_ini_refresh_caches(ZEND_INI_STAGE_STARTUP TSRMLS_CC);
350609d58a4SZeev Suraski}
351609d58a4SZeev Suraski
35266d9314bSZeev Suraski#endif
35366d9314bSZeev Suraski
35466d9314bSZeev Suraski
355b4f3b9d3SZeev Suraskistatic void alloc_globals_ctor(zend_alloc_globals *alloc_globals_p TSRMLS_DC)
3567c4a0838SZeev Suraski{
357b4f3b9d3SZeev Suraski	start_memory_manager(TSRMLS_C);
3587c4a0838SZeev Suraski}
3597c4a0838SZeev Suraski
3607a87fcbbSZeev Suraski
361fcc03510SZeev Suraskistatic void alloc_globals_dtor(zend_alloc_globals *alloc_globals_p TSRMLS_DC)
362fcc03510SZeev Suraski{
3637df16012SAndi Gutmans	shutdown_memory_manager(0, 1 TSRMLS_CC);
364fcc03510SZeev Suraski}
365fcc03510SZeev Suraski
366fcc03510SZeev Suraski
3671f5ee72eSAndi Gutmans#ifdef __FreeBSD__
3685928970dSAndi Gutmans/* FreeBSD floating point precision fix */
3695928970dSAndi Gutmans#include <floatingpoint.h>
3705928970dSAndi Gutmans#endif
3717a87fcbbSZeev Suraski
372609d58a4SZeev Suraski
373609d58a4SZeev Suraskistatic void scanner_globals_ctor(zend_scanner_globals *scanner_globals_p TSRMLS_DC)
37454d53055SZeev Suraski{
375609d58a4SZeev Suraski	scanner_globals_p->c_buf_p = (char *) 0;
376609d58a4SZeev Suraski	scanner_globals_p->init = 1;
377609d58a4SZeev Suraski	scanner_globals_p->start = 0;
378609d58a4SZeev Suraski	scanner_globals_p->current_buffer = NULL;
379483fc4c7SZeev Suraski	scanner_globals_p->yy_in = NULL;
380483fc4c7SZeev Suraski	scanner_globals_p->yy_out = NULL;
38117352812SZeev Suraski	scanner_globals_p->_yy_more_flag = 0;
38217352812SZeev Suraski	scanner_globals_p->_yy_more_len = 0;
38317352812SZeev Suraski
38454d53055SZeev Suraski}
38554d53055SZeev Suraski
38654d53055SZeev Suraski
38713e74131SAndi Gutmansint zend_startup(zend_utility_functions *utility_functions, char **extensions, int start_builtin_functions)
388573b4602SAndi Gutmans{
389a9f9ae79SZeev Suraski#ifdef ZTS
3907c4a0838SZeev Suraski	zend_compiler_globals *compiler_globals;
391a9f9ae79SZeev Suraski	zend_executor_globals *executor_globals;
3922c254ba7SZeev Suraski	void ***tsrm_ls;
393609d58a4SZeev Suraski#ifdef ZTS
394609d58a4SZeev Suraski	extern ZEND_API ts_rsrc_id ini_scanner_globals_id;
395609d58a4SZeev Suraski	extern ZEND_API ts_rsrc_id language_scanner_globals_id;
396609d58a4SZeev Suraski#else
397609d58a4SZeev Suraski	extern zend_scanner_globals ini_scanner_globals;
398609d58a4SZeev Suraski	extern zend_scanner_globals language_scanner_globals;
399609d58a4SZeev Suraski#endif
400a9f9ae79SZeev Suraski
401fcc03510SZeev Suraski	ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor);
40299947a25SAndi Gutmans#else
40366d9314bSZeev Suraski	alloc_globals_ctor(&alloc_globals TSRMLS_CC);
404a9f9ae79SZeev Suraski#endif
405a9f9ae79SZeev Suraski
4061f5ee72eSAndi Gutmans#ifdef __FreeBSD__
407c3340584SSascha Schumann	/* FreeBSD floating point precision fix */
408c3340584SSascha Schumann	fpsetmask(0);
4095928970dSAndi Gutmans#endif
410309827ecSZeev Suraski
411309827ecSZeev Suraski	zend_startup_extensions_mechanism();
412309827ecSZeev Suraski
413573b4602SAndi Gutmans	/* Set up utility functions and values */
41467f69743SZeev Suraski	zend_error_cb = utility_functions->error_function;
415573b4602SAndi Gutmans	zend_printf = utility_functions->printf_function;
4165dba4774SZeev Suraski	zend_write = (zend_write_func_t) utility_functions->write_function;
417573b4602SAndi Gutmans	zend_fopen = utility_functions->fopen_function;
418573b4602SAndi Gutmans	if (!zend_fopen) {
419573b4602SAndi Gutmans		zend_fopen = zend_fopen_wrapper;
420573b4602SAndi Gutmans	}
42156251a72SZeev Suraski	zend_message_dispatcher_p = utility_functions->message_handler;
422573b4602SAndi Gutmans	zend_block_interruptions = utility_functions->block_interruptions;
423573b4602SAndi Gutmans	zend_unblock_interruptions = utility_functions->unblock_interruptions;
424903018efSZeev Suraski	zend_get_configuration_directive_p = utility_functions->get_configuration_directive;
425fafbf6d8SZeev Suraski	zend_ticks_function = utility_functions->ticks_function;
426d035af4aSZeev Suraski
427c06692e9SZeev Suraski	zend_compile_file = compile_file;
428573b4602SAndi Gutmans	zend_execute = execute;
429573b4602SAndi Gutmans
430573b4602SAndi Gutmans	/* set up version */
431573b4602SAndi Gutmans	zend_version_info = strdup(ZEND_CORE_VERSION_INFO);
432573b4602SAndi Gutmans	zend_version_info_length = sizeof(ZEND_CORE_VERSION_INFO)-1;
433573b4602SAndi Gutmans
434ce98c73fSAndi Gutmans#ifndef ZTS
435ce98c73fSAndi Gutmans	GLOBAL_FUNCTION_TABLE = &compiler_globals.main_class.function_table;
436ce98c73fSAndi Gutmans	GLOBAL_CLASS_TABLE = &compiler_globals.main_class.class_table;
437ce98c73fSAndi Gutmans#endif
4389d11db12SAndi Gutmans	GLOBAL_AUTO_GLOBALS_TABLE = (HashTable *) malloc(sizeof(HashTable));
4391263932aSZeev Suraski	zend_hash_init_ex(GLOBAL_FUNCTION_TABLE, 100, NULL, ZEND_FUNCTION_DTOR, 1, 0);
4401263932aSZeev Suraski	zend_hash_init_ex(GLOBAL_CLASS_TABLE, 10, NULL, ZEND_CLASS_DTOR, 1, 0);
4419d11db12SAndi Gutmans	zend_hash_init_ex(GLOBAL_AUTO_GLOBALS_TABLE, 8, NULL, NULL, 1, 0);
4422eabb14dSAndi Gutmans
443573b4602SAndi Gutmans	register_standard_class();
4441263932aSZeev Suraski	zend_hash_init_ex(&module_registry, 50, NULL, ZEND_MODULE_DTOR, 1, 0);
4454cb9a483SZeev Suraski	zend_init_rsrc_list_dtors();
446573b4602SAndi Gutmans
447213d0e2fSAndi Gutmans	/* This zval can be used to initialize allocate zval's to an uninit'ed value */
448213d0e2fSAndi Gutmans	zval_used_for_init.is_ref = 0;
449213d0e2fSAndi Gutmans	zval_used_for_init.refcount = 1;
450bdefd5daSAndi Gutmans	zval_used_for_init.type = IS_NULL;
451213d0e2fSAndi Gutmans
4527a87fcbbSZeev Suraski#ifdef ZTS
4532c254ba7SZeev Suraski	ts_allocate_id(&compiler_globals_id, sizeof(zend_compiler_globals), (ts_allocate_ctor) compiler_globals_ctor, (ts_allocate_dtor) compiler_globals_dtor);
4542c254ba7SZeev Suraski	ts_allocate_id(&executor_globals_id, sizeof(zend_executor_globals), (ts_allocate_ctor) executor_globals_ctor, (ts_allocate_dtor) executor_globals_dtor);
455609d58a4SZeev Suraski	ts_allocate_id(&language_scanner_globals_id, sizeof(zend_scanner_globals), (ts_allocate_ctor) scanner_globals_ctor, NULL);
456609d58a4SZeev Suraski	ts_allocate_id(&ini_scanner_globals_id, sizeof(zend_scanner_globals), (ts_allocate_ctor) scanner_globals_ctor, NULL);
4577c4a0838SZeev Suraski	compiler_globals = ts_resource(compiler_globals_id);
458a9f9ae79SZeev Suraski	executor_globals = ts_resource(executor_globals_id);
4592c254ba7SZeev Suraski	tsrm_ls = ts_resource_ex(0, NULL);
4602c254ba7SZeev Suraski	compiler_globals_dtor(compiler_globals, tsrm_ls);
461f4b832d2SAndi Gutmans	*compiler_globals->function_table = *GLOBAL_FUNCTION_TABLE;
462f4b832d2SAndi Gutmans	*compiler_globals->class_table = *GLOBAL_CLASS_TABLE;
4639d11db12SAndi Gutmans	compiler_globals->auto_globals = GLOBAL_AUTO_GLOBALS_TABLE;
4642c254ba7SZeev Suraski	zend_startup_constants(tsrm_ls);
465762158aaSAndi Gutmans#else
46680b870e5SAndi Gutmans	zend_hash_init_ex(CG(auto_globals), 8, NULL, NULL, 1, 0);
467609d58a4SZeev Suraski	scanner_globals_ctor(&ini_scanner_globals TSRMLS_CC);
468609d58a4SZeev Suraski	scanner_globals_ctor(&language_scanner_globals TSRMLS_CC);
4696313238cSZeev Suraski	zend_startup_constants();
470b4f3b9d3SZeev Suraski	zend_set_default_compile_time_values(TSRMLS_C);
4711f23e507SZeev Suraski	EG(user_error_handler) = NULL;
4727a87fcbbSZeev Suraski#endif
4732c254ba7SZeev Suraski	zend_register_standard_constants(TSRMLS_C);
4747a87fcbbSZeev Suraski
475bfbe8618SZeev Suraski#ifndef ZTS
4762c254ba7SZeev Suraski	zend_init_rsrc_plist(TSRMLS_C);
477bfbe8618SZeev Suraski#endif
478a9f9ae79SZeev Suraski
47913e74131SAndi Gutmans	if (start_builtin_functions) {
480b5770382SZeev Suraski		zend_startup_builtin_functions(TSRMLS_C);
48113e74131SAndi Gutmans	}
48213d840bcSZeev Suraski
4832c254ba7SZeev Suraski	zend_ini_startup(TSRMLS_C);
48454d53055SZeev Suraski
48554d53055SZeev Suraski#ifdef ZTS
48654d53055SZeev Suraski	tsrm_set_new_thread_end_handler(zend_new_thread_end_handler);
4873458373eSAndi Gutmans	*GLOBAL_FUNCTION_TABLE = *compiler_globals->function_table;
4883458373eSAndi Gutmans	*GLOBAL_CLASS_TABLE = *compiler_globals->class_table;
48954d53055SZeev Suraski#endif
49054d53055SZeev Suraski
491573b4602SAndi Gutmans	return SUCCESS;
492573b4602SAndi Gutmans}
493573b4602SAndi Gutmans
494573b4602SAndi Gutmans
495d76cf1daSZeev Suraskivoid zend_shutdown(TSRMLS_D)
496573b4602SAndi Gutmans{
49784eb48f0SZeev Suraski#ifdef ZEND_WIN32
49884eb48f0SZeev Suraski	zend_shutdown_timeout_thread();
49984eb48f0SZeev Suraski#endif
500bfbe8618SZeev Suraski#ifndef ZTS
5017deb44e3SZeev Suraski	zend_destroy_rsrc_list(&EG(persistent_list) TSRMLS_CC);
502bfbe8618SZeev Suraski#endif
5034cb9a483SZeev Suraski	zend_destroy_rsrc_list_dtors();
504573b4602SAndi Gutmans	zend_hash_destroy(&module_registry);
5053458373eSAndi Gutmans
50676b9acc1SAndi Gutmans#ifndef ZTS
50776b9acc1SAndi Gutmans	/* In ZTS mode these are freed by compiler_globals_dtor() */
5087a87fcbbSZeev Suraski	zend_hash_destroy(GLOBAL_FUNCTION_TABLE);
50976b9acc1SAndi Gutmans	zend_hash_destroy(GLOBAL_CLASS_TABLE);
51076b9acc1SAndi Gutmans#endif
5113458373eSAndi Gutmans
5129d11db12SAndi Gutmans	zend_hash_destroy(GLOBAL_AUTO_GLOBALS_TABLE);
5139d11db12SAndi Gutmans	free(GLOBAL_AUTO_GLOBALS_TABLE);
514d76cf1daSZeev Suraski	zend_shutdown_extensions(TSRMLS_C);
515573b4602SAndi Gutmans	free(zend_version_info);
5167a87fcbbSZeev Suraski#ifndef ZTS
517ee08b81aSZeev Suraski	zend_shutdown_constants();
5187a87fcbbSZeev Suraski#endif
519573b4602SAndi Gutmans}
520573b4602SAndi Gutmans
521573b4602SAndi Gutmans
5227656c77cSZeev Suraskivoid zend_set_utility_values(zend_utility_values *utility_values)
5237656c77cSZeev Suraski{
5247656c77cSZeev Suraski	zend_uv = *utility_values;
5259baad804SZeev Suraski	zend_uv.import_use_extension_length = strlen(zend_uv.import_use_extension);
5267656c77cSZeev Suraski}
5277656c77cSZeev Suraski
5287656c77cSZeev Suraski
529573b4602SAndi Gutmans/* this should be compatible with the standard zenderror */
530573b4602SAndi Gutmansvoid zenderror(char *error)
531573b4602SAndi Gutmans{
532573b4602SAndi Gutmans	zend_error(E_PARSE, error);
533573b4602SAndi Gutmans}
534573b4602SAndi Gutmans
535573b4602SAndi Gutmans
536b0bfa458SZeev SuraskiBEGIN_EXTERN_C()
537ef4fe54fSZeev SuraskiZEND_API void _zend_bailout(char *filename, uint lineno)
538573b4602SAndi Gutmans{
5392c254ba7SZeev Suraski	TSRMLS_FETCH();
540573b4602SAndi Gutmans
541931ebe08SZeev Suraski	if (!EG(bailout_set)) {
542ef4fe54fSZeev Suraski		zend_output_debug_string(1, "%s(%d) : Bailed out without a bailout address!", filename, lineno);
543931ebe08SZeev Suraski		exit(-1);
544931ebe08SZeev Suraski	}
5456bc6dacfSZeev Suraski	CG(unclean_shutdown) = 1;
546b23d83cfSZeev Suraski	CG(in_compilation) = EG(in_execution) = 0;
547573b4602SAndi Gutmans	longjmp(EG(bailout), FAILURE);
548573b4602SAndi Gutmans}
549b0bfa458SZeev SuraskiEND_EXTERN_C()
550573b4602SAndi Gutmans
551573b4602SAndi Gutmans
552573b4602SAndi Gutmansvoid zend_append_version_info(zend_extension *extension)
553573b4602SAndi Gutmans{
554573b4602SAndi Gutmans	char *new_info;
555573b4602SAndi Gutmans	uint new_info_length;
556573b4602SAndi Gutmans
557573b4602SAndi Gutmans	new_info_length = sizeof("    with  v,  by \n")
558573b4602SAndi Gutmans						+ strlen(extension->name)
559573b4602SAndi Gutmans						+ strlen(extension->version)
560573b4602SAndi Gutmans						+ strlen(extension->copyright)
561573b4602SAndi Gutmans						+ strlen(extension->author);
562573b4602SAndi Gutmans
563573b4602SAndi Gutmans	new_info = (char *) malloc(new_info_length+1);
564573b4602SAndi Gutmans
565573b4602SAndi Gutmans	sprintf(new_info, "    with %s v%s, %s, by %s\n", extension->name, extension->version, extension->copyright, extension->author);
566573b4602SAndi Gutmans
567573b4602SAndi Gutmans	zend_version_info = (char *) realloc(zend_version_info, zend_version_info_length+new_info_length+1);
568573b4602SAndi Gutmans	strcat(zend_version_info, new_info);
569573b4602SAndi Gutmans	zend_version_info_length += new_info_length;
570573b4602SAndi Gutmans	free(new_info);
571573b4602SAndi Gutmans}
572573b4602SAndi Gutmans
573573b4602SAndi Gutmans
574573b4602SAndi GutmansZEND_API char *get_zend_version()
575573b4602SAndi Gutmans{
576573b4602SAndi Gutmans	return zend_version_info;
577573b4602SAndi Gutmans}
578ed06a70fSZeev Suraski
579ed06a70fSZeev Suraski
580b4f3b9d3SZeev Suraskivoid zend_activate(TSRMLS_D)
581ed06a70fSZeev Suraski{
582b4f3b9d3SZeev Suraski	init_compiler(TSRMLS_C);
583b4f3b9d3SZeev Suraski	init_executor(TSRMLS_C);
584b4f3b9d3SZeev Suraski	startup_scanner(TSRMLS_C);
585ed06a70fSZeev Suraski}
586ed06a70fSZeev Suraski
587dc0e6632SZeev Suraski
588d76cf1daSZeev Suraskivoid zend_activate_modules(TSRMLS_D)
589dc0e6632SZeev Suraski{
590d76cf1daSZeev Suraski	zend_hash_apply(&module_registry, (apply_func_t) module_registry_request_startup TSRMLS_CC);
591dc0e6632SZeev Suraski}
592dc0e6632SZeev Suraski
593b5770382SZeev Suraskivoid zend_deactivate_modules(TSRMLS_D)
594a8b0d960SAndi Gutmans{
595a8b0d960SAndi Gutmans	EG(opline_ptr) = NULL; /* we're no longer executing anything */
596a8b0d960SAndi Gutmans
597931ebe08SZeev Suraski	zend_try {
598d76cf1daSZeev Suraski		zend_hash_apply(&module_registry, (apply_func_t) module_registry_cleanup TSRMLS_CC);
599931ebe08SZeev Suraski	} zend_end_try();
600a8b0d960SAndi Gutmans}
601dc0e6632SZeev Suraski
602b4f3b9d3SZeev Suraskivoid zend_deactivate(TSRMLS_D)
603ed06a70fSZeev Suraski{
604372f71ebSThies C. Arntzen	/* we're no longer executing anything */
605372f71ebSThies C. Arntzen	EG(opline_ptr) = NULL;
606372f71ebSThies C. Arntzen	EG(active_symbol_table) = NULL;
607f4c9d96fSThies C. Arntzen
608931ebe08SZeev Suraski	zend_try {
609b4f3b9d3SZeev Suraski		shutdown_scanner(TSRMLS_C);
610931ebe08SZeev Suraski	} zend_end_try();
611931ebe08SZeev Suraski
6128084d278SZeev Suraski	/* shutdown_executor() takes care of its own bailout handling */
6132c254ba7SZeev Suraski	shutdown_executor(TSRMLS_C);
614931ebe08SZeev Suraski
615931ebe08SZeev Suraski	zend_try {
616b4f3b9d3SZeev Suraski		shutdown_compiler(TSRMLS_C);
617931ebe08SZeev Suraski	} zend_end_try();
618931ebe08SZeev Suraski
619931ebe08SZeev Suraski	zend_try {
6202c254ba7SZeev Suraski		zend_ini_deactivate(TSRMLS_C);
621931ebe08SZeev Suraski	} zend_end_try();
622ed06a70fSZeev Suraski}
62356251a72SZeev Suraski
62456251a72SZeev Suraski
625fc173b6aSSam RubyBEGIN_EXTERN_C()
62656251a72SZeev SuraskiZEND_API void zend_message_dispatcher(long message, void *data)
62756251a72SZeev Suraski{
62856251a72SZeev Suraski	if (zend_message_dispatcher_p) {
62956251a72SZeev Suraski		zend_message_dispatcher_p(message, data);
63056251a72SZeev Suraski	}
63156251a72SZeev Suraski}
632fc173b6aSSam RubyEND_EXTERN_C()
63356251a72SZeev Suraski
63456251a72SZeev Suraski
635903018efSZeev SuraskiZEND_API int zend_get_configuration_directive(char *name, uint name_length, zval *contents)
63656251a72SZeev Suraski{
637903018efSZeev Suraski	if (zend_get_configuration_directive_p) {
638903018efSZeev Suraski		return zend_get_configuration_directive_p(name, name_length, contents);
63956251a72SZeev Suraski	} else {
64056251a72SZeev Suraski		return FAILURE;
64156251a72SZeev Suraski	}
64256251a72SZeev Suraski}
64367f69743SZeev Suraski
64467f69743SZeev Suraski
64567f69743SZeev Suraski#define ZEND_ERROR_BUFFER_SIZE 1024
64667f69743SZeev Suraski
64767f69743SZeev SuraskiZEND_API void zend_error(int type, const char *format, ...)
64867f69743SZeev Suraski{
64967f69743SZeev Suraski	va_list args;
6503cda6a75SZeev Suraski	zval ***params;
6513cda6a75SZeev Suraski	zval *retval;
652f34b9d41SZeev Suraski	zval *z_error_type, *z_error_message, *z_error_filename, *z_error_lineno, *z_context;
653b80b8381SZeev Suraski	char *error_filename;
654b80b8381SZeev Suraski	uint error_lineno;
655a31dc47aSZeev Suraski	zval *orig_user_error_handler;
6562c254ba7SZeev Suraski	TSRMLS_FETCH();
65767f69743SZeev Suraski
658b80b8381SZeev Suraski	/* Obtain relevant filename and lineno */
659b80b8381SZeev Suraski	switch (type) {
660b80b8381SZeev Suraski		case E_CORE_ERROR:
661b80b8381SZeev Suraski		case E_CORE_WARNING:
662b80b8381SZeev Suraski			error_filename = NULL;
663b80b8381SZeev Suraski			error_lineno = 0;
664b80b8381SZeev Suraski			break;
665b80b8381SZeev Suraski		case E_PARSE:
666b80b8381SZeev Suraski		case E_COMPILE_ERROR:
667b80b8381SZeev Suraski		case E_COMPILE_WARNING:
668b80b8381SZeev Suraski		case E_ERROR:
669b80b8381SZeev Suraski		case E_NOTICE:
670b80b8381SZeev Suraski		case E_WARNING:
671b80b8381SZeev Suraski		case E_USER_ERROR:
672b80b8381SZeev Suraski		case E_USER_WARNING:
673b80b8381SZeev Suraski		case E_USER_NOTICE:
6744187439cSZeev Suraski			if (zend_is_compiling(TSRMLS_C)) {
675b4f3b9d3SZeev Suraski				error_filename = zend_get_compiled_filename(TSRMLS_C);
676b4f3b9d3SZeev Suraski				error_lineno = zend_get_compiled_lineno(TSRMLS_C);
6774187439cSZeev Suraski			} else if (zend_is_executing(TSRMLS_C)) {
6782c254ba7SZeev Suraski				error_filename = zend_get_executed_filename(TSRMLS_C);
6792c254ba7SZeev Suraski				error_lineno = zend_get_executed_lineno(TSRMLS_C);
680b80b8381SZeev Suraski			} else {
681b80b8381SZeev Suraski				error_filename = NULL;
682b80b8381SZeev Suraski				error_lineno = 0;
683b80b8381SZeev Suraski			}
684b80b8381SZeev Suraski			break;
685b80b8381SZeev Suraski		default:
686b80b8381SZeev Suraski			error_filename = NULL;
687b80b8381SZeev Suraski			error_lineno = 0;
688b80b8381SZeev Suraski			break;
689b80b8381SZeev Suraski	}
690b80b8381SZeev Suraski	if (!error_filename) {
691b80b8381SZeev Suraski		error_filename = "Unknown";
692b80b8381SZeev Suraski	}
69367f69743SZeev Suraski
69467f69743SZeev Suraski
695b80b8381SZeev Suraski	va_start(args, format);
6968a8c3eafSZeev Suraski
69767f69743SZeev Suraski	/* if we don't have a user defined error handler */
69867f69743SZeev Suraski	if (!EG(user_error_handler)) {
699b80b8381SZeev Suraski		zend_error_cb(type, error_filename, error_lineno, format, args);
700b80b8381SZeev Suraski	} else switch (type) {
70167f69743SZeev Suraski		case E_ERROR:
70267f69743SZeev Suraski		case E_PARSE:
70367f69743SZeev Suraski		case E_CORE_ERROR:
70467f69743SZeev Suraski		case E_CORE_WARNING:
70567f69743SZeev Suraski		case E_COMPILE_ERROR:
70667f69743SZeev Suraski		case E_COMPILE_WARNING:
707b80b8381SZeev Suraski			/* The error may not be safe to handle in user-space */
708b80b8381SZeev Suraski			zend_error_cb(type, error_filename, error_lineno, format, args);
709b80b8381SZeev Suraski			break;
710b80b8381SZeev Suraski		default:
711b80b8381SZeev Suraski			/* Handle the error in user space */
712f34b9d41SZeev Suraski			ALLOC_INIT_ZVAL(z_error_message);
713f34b9d41SZeev Suraski			ALLOC_INIT_ZVAL(z_error_type);
714a31dc47aSZeev Suraski			ALLOC_INIT_ZVAL(z_error_filename);
715a31dc47aSZeev Suraski			ALLOC_INIT_ZVAL(z_error_lineno);
716f34b9d41SZeev Suraski			ALLOC_INIT_ZVAL(z_context);
717f34b9d41SZeev Suraski			z_error_message->value.str.val = (char *) emalloc(ZEND_ERROR_BUFFER_SIZE);
71867f69743SZeev Suraski
7198a8c3eafSZeev Suraski#ifdef HAVE_VSNPRINTF
720f34b9d41SZeev Suraski			z_error_message->value.str.len = vsnprintf(z_error_message->value.str.val, ZEND_ERROR_BUFFER_SIZE, format, args);
7214acff8f3SZeev Suraski			if (z_error_message->value.str.len > ZEND_ERROR_BUFFER_SIZE-1) {
722d10336ecSStanislav Malyshev				z_error_message->value.str.len = ZEND_ERROR_BUFFER_SIZE-1;
723d10336ecSStanislav Malyshev			}
7248a8c3eafSZeev Suraski#else
7254acff8f3SZeev Suraski			strncpy(z_error_message->value.str.val, format, ZEND_ERROR_BUFFER_SIZE);
7268a8c3eafSZeev Suraski			/* This is risky... */
7274acff8f3SZeev Suraski			/* z_error_message->value.str.len = vsprintf(z_error_message->value.str.val, format, args); */
7288a8c3eafSZeev Suraski#endif
729f34b9d41SZeev Suraski			z_error_message->type = IS_STRING;
73067f69743SZeev Suraski
731f34b9d41SZeev Suraski			z_error_type->value.lval = type;
732f34b9d41SZeev Suraski			z_error_type->type = IS_LONG;
73367f69743SZeev Suraski
734a31dc47aSZeev Suraski			if (error_filename) {
735a31dc47aSZeev Suraski				z_error_filename->value.str.len = strlen(error_filename);
736a31dc47aSZeev Suraski				z_error_filename->value.str.val = estrndup(error_filename, z_error_filename->value.str.len);
737a31dc47aSZeev Suraski				z_error_filename->type = IS_STRING;
738a31dc47aSZeev Suraski			}
739a31dc47aSZeev Suraski
740a31dc47aSZeev Suraski			z_error_lineno->value.lval = error_lineno;
741a31dc47aSZeev Suraski			z_error_lineno->type = IS_LONG;
742a31dc47aSZeev Suraski
743f34b9d41SZeev Suraski			z_context->value.ht = EG(active_symbol_table);
744f34b9d41SZeev Suraski			z_context->type = IS_ARRAY;
745f34b9d41SZeev Suraski			ZVAL_ADDREF(z_context);  /* we don't want this one to be freed */
746f34b9d41SZeev Suraski
747f34b9d41SZeev Suraski			params = (zval ***) emalloc(sizeof(zval **)*5);
748f34b9d41SZeev Suraski			params[0] = &z_error_type;
749f34b9d41SZeev Suraski			params[1] = &z_error_message;
750a31dc47aSZeev Suraski			params[2] = &z_error_filename;
751a31dc47aSZeev Suraski			params[3] = &z_error_lineno;
752f34b9d41SZeev Suraski			params[4] = &z_context;
75367f69743SZeev Suraski
754a31dc47aSZeev Suraski			orig_user_error_handler = EG(user_error_handler);
755a31dc47aSZeev Suraski			EG(user_error_handler) = NULL;
7564187439cSZeev Suraski			if (call_user_function_ex(CG(function_table), NULL, orig_user_error_handler, &retval, 5, params, 1, NULL TSRMLS_CC)==SUCCESS) {
7573cda6a75SZeev Suraski				zval_ptr_dtor(&retval);
758b80b8381SZeev Suraski			} else {
759b80b8381SZeev Suraski				/* The user error handler failed, use built-in error handler */
760b80b8381SZeev Suraski				zend_error_cb(type, error_filename, error_lineno, format, args);
761b80b8381SZeev Suraski			}
762a31dc47aSZeev Suraski			EG(user_error_handler) = orig_user_error_handler;
763a31dc47aSZeev Suraski
764b80b8381SZeev Suraski			efree(params);
765f34b9d41SZeev Suraski			zval_ptr_dtor(&z_error_message);
766f34b9d41SZeev Suraski			zval_ptr_dtor(&z_error_type);
767a31dc47aSZeev Suraski			zval_ptr_dtor(&z_error_filename);
768a31dc47aSZeev Suraski			zval_ptr_dtor(&z_error_lineno);
769f34b9d41SZeev Suraski			if (ZVAL_REFCOUNT(z_context)==2) {
770f34b9d41SZeev Suraski				FREE_ZVAL(z_context);
771f34b9d41SZeev Suraski			}
772b80b8381SZeev Suraski			break;
77367f69743SZeev Suraski	}
774b80b8381SZeev Suraski
775b80b8381SZeev Suraski	va_end(args);
776bda9c83aSZeev Suraski
777bda9c83aSZeev Suraski	if (type==E_PARSE) {
778b4f3b9d3SZeev Suraski		zend_init_compiler_data_structures(TSRMLS_C);
779bda9c83aSZeev Suraski	}
78067f69743SZeev Suraski}
78167f69743SZeev Suraski
7820b7a9ceaSZeev Suraski
7830b7a9ceaSZeev SuraskiZEND_API void zend_output_debug_string(zend_bool trigger_break, char *format, ...)
7840b7a9ceaSZeev Suraski{
7850b7a9ceaSZeev Suraski#if ZEND_DEBUG
7860b7a9ceaSZeev Suraski	va_list args;
7870b7a9ceaSZeev Suraski
7880b7a9ceaSZeev Suraski	va_start(args, format);
78901d478baSAndi Gutmans#	ifdef ZEND_WIN32
7900b7a9ceaSZeev Suraski	{
7910b7a9ceaSZeev Suraski		char output_buf[1024];
7920b7a9ceaSZeev Suraski
7930b7a9ceaSZeev Suraski		vsnprintf(output_buf, 1024, format, args);
7940b7a9ceaSZeev Suraski		OutputDebugString(output_buf);
7950b7a9ceaSZeev Suraski		OutputDebugString("\n");
7960b7a9ceaSZeev Suraski		if (trigger_break && IsDebuggerPresent()) {
7970b7a9ceaSZeev Suraski			DebugBreak();
7980b7a9ceaSZeev Suraski		}
7990b7a9ceaSZeev Suraski	}
8000b7a9ceaSZeev Suraski#	else
8010b7a9ceaSZeev Suraski	vfprintf(stderr, format, args);
8020b7a9ceaSZeev Suraski	fprintf(stderr, "\n");
8030b7a9ceaSZeev Suraski#	endif
8040b7a9ceaSZeev Suraski	va_end(args);
8050b7a9ceaSZeev Suraski#endif
8060b7a9ceaSZeev Suraski}
807c06692e9SZeev Suraski
808c06692e9SZeev Suraski
809819ea51dSZeev SuraskiZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval **retval, int file_count, ...)
810c06692e9SZeev Suraski{
811c06692e9SZeev Suraski	va_list files;
812c06692e9SZeev Suraski	int i;
813c06692e9SZeev Suraski	zend_file_handle *file_handle;
8140eadc7e4SZeev Suraski	zend_op_array *orig_op_array = EG(active_op_array);
815b06440bcSZeev Suraski	zval *local_retval=NULL;
816c06692e9SZeev Suraski
817c06692e9SZeev Suraski	va_start(files, file_count);
818c06692e9SZeev Suraski	for (i=0; i<file_count; i++) {
819c06692e9SZeev Suraski		file_handle = va_arg(files, zend_file_handle *);
820c06692e9SZeev Suraski		if (!file_handle) {
821c06692e9SZeev Suraski			continue;
822c06692e9SZeev Suraski		}
823b4f3b9d3SZeev Suraski		EG(active_op_array) = zend_compile_file(file_handle, ZEND_INCLUDE TSRMLS_CC);
824b4f3b9d3SZeev Suraski		zend_destroy_file_handle(file_handle TSRMLS_CC);
825c06692e9SZeev Suraski		if (EG(active_op_array)) {
826b06440bcSZeev Suraski			EG(return_value_ptr_ptr) = retval ? retval : &local_retval;
8272c254ba7SZeev Suraski			zend_execute(EG(active_op_array) TSRMLS_CC);
82884603723SAndi Gutmans			if (EG(exception)) {
82984603723SAndi Gutmans				zval_ptr_dtor(&EG(exception));
830b9355b9aSAndi Gutmans				zend_error(E_ERROR, "Uncaught exception!");
83184603723SAndi Gutmans			} else if (!retval) {
832b06440bcSZeev Suraski				zval_ptr_dtor(EG(return_value_ptr_ptr));
833b06440bcSZeev Suraski				local_retval = NULL;
834819ea51dSZeev Suraski			}
835c06692e9SZeev Suraski			destroy_op_array(EG(active_op_array));
836c06692e9SZeev Suraski			efree(EG(active_op_array));
837c06692e9SZeev Suraski		} else if (type==ZEND_REQUIRE) {
838c06692e9SZeev Suraski			va_end(files);
8390eadc7e4SZeev Suraski			EG(active_op_array) = orig_op_array;
840c06692e9SZeev Suraski			return FAILURE;
841c06692e9SZeev Suraski		}
842c06692e9SZeev Suraski	}
843c06692e9SZeev Suraski	va_end(files);
8440eadc7e4SZeev Suraski	EG(active_op_array) = orig_op_array;
845c06692e9SZeev Suraski
846c06692e9SZeev Suraski	return SUCCESS;
847c06692e9SZeev Suraski}
848c06692e9SZeev Suraski
8495286b397SZeev Suraski#define COMPILED_STRING_DESCRIPTION_FORMAT "%s(%d) : %s"
8505286b397SZeev Suraski
851b5770382SZeev SuraskiZEND_API char *zend_make_compiled_string_description(char *name TSRMLS_DC)
8525286b397SZeev Suraski{
8535286b397SZeev Suraski	char *cur_filename;
8545286b397SZeev Suraski	int cur_lineno;
8555286b397SZeev Suraski	char *compiled_string_description;
8565286b397SZeev Suraski
8574187439cSZeev Suraski	if (zend_is_compiling(TSRMLS_C)) {
858b4f3b9d3SZeev Suraski		cur_filename = zend_get_compiled_filename(TSRMLS_C);
859b4f3b9d3SZeev Suraski		cur_lineno = zend_get_compiled_lineno(TSRMLS_C);
8604187439cSZeev Suraski	} else if (zend_is_executing(TSRMLS_C)) {
8612c254ba7SZeev Suraski		cur_filename = zend_get_executed_filename(TSRMLS_C);
8622c254ba7SZeev Suraski		cur_lineno = zend_get_executed_lineno(TSRMLS_C);
8635286b397SZeev Suraski	} else {
8645286b397SZeev Suraski		cur_filename = "Unknown";
8655286b397SZeev Suraski		cur_lineno = 0;
8665286b397SZeev Suraski	}
8675286b397SZeev Suraski
8685286b397SZeev Suraski	compiled_string_description = emalloc(sizeof(COMPILED_STRING_DESCRIPTION_FORMAT)+strlen(name)+strlen(cur_filename)+MAX_LENGTH_OF_LONG);
8695286b397SZeev Suraski	sprintf(compiled_string_description, COMPILED_STRING_DESCRIPTION_FORMAT, cur_filename, cur_lineno, name);
8705286b397SZeev Suraski	return compiled_string_description;
8715286b397SZeev Suraski}
8725286b397SZeev Suraski
8730e08845eSZeev Suraski
8740e08845eSZeev Suraskivoid free_estring(char **str_p)
8750e08845eSZeev Suraski{
8760e08845eSZeev Suraski	efree(*str_p);
8770e08845eSZeev Suraski}
878