Annotation of embedaddon/php/Zend/zend.c, revision 1.1.1.3
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | Zend Engine |
4: +----------------------------------------------------------------------+
1.1.1.3 ! misho 5: | Copyright (c) 1998-2013 Zend Technologies Ltd. (http://www.zend.com) |
1.1 misho 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:
1.1.1.2 misho 20: /* $Id$ */
1.1 misho 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"
1.1.1.2 misho 32: #include "zend_dtrace.h"
1.1 misho 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:
1.1.1.2 misho 66: static void (*zend_message_dispatcher_p)(long message, const void *data TSRMLS_DC);
1.1 misho 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:
1.1.1.2 misho 92: static ZEND_INI_MH(OnUpdateScriptEncoding) /* {{{ */
1.1 misho 93: {
1.1.1.2 misho 94: if (!CG(multibyte)) {
95: return FAILURE;
1.1 misho 96: }
1.1.1.2 misho 97: if (!zend_multibyte_get_functions(TSRMLS_C)) {
98: return SUCCESS;
1.1 misho 99: }
1.1.1.2 misho 100: return zend_multibyte_set_script_encoding_by_string(new_value, new_value_length TSRMLS_CC);
1.1 misho 101: }
1.1.1.2 misho 102: /* }}} */
103:
1.1 misho 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)
1.1.1.2 misho 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)
1.1 misho 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;
1.1.1.3 ! misho 134: #define ZEND_CORE_VERSION_INFO "Zend Engine v" ZEND_VERSION ", Copyright (c) 1998-2013 Zend Technologies\n"
1.1 misho 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) {
1.1.1.2 misho 160: const char *prop_name, *class_name;
1.1 misho 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);
1.1.1.2 misho 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));
1.1 misho 251: break;
252: case IS_ARRAY:
1.1.1.2 misho 253: zend_error(E_NOTICE, "Array to string conversion");
1.1 misho 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:
1.1.1.3 ! misho 261: if (zend_std_cast_object_tostring(expr, expr_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
! 262: break;
! 263: }
1.1.1.2 misho 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);
1.1 misho 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;
1.1.1.2 misho 359: const char *class_name = NULL;
1.1 misho 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) {
1.1.1.2 misho 371: efree((char*)class_name);
1.1 misho 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;
1.1.1.2 misho 417: const char *class_name = NULL;
1.1 misho 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) {
1.1.1.2 misho 431: efree((char*)class_name);
1.1 misho 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;
1.1.1.2 misho 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;
1.1 misho 491: ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op));
492: EG(exception_op)[1].opcode = ZEND_HANDLE_EXCEPTION;
1.1.1.2 misho 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;
1.1 misho 496: ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op)+1);
497: EG(exception_op)[2].opcode = ZEND_HANDLE_EXCEPTION;
1.1.1.2 misho 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;
1.1 misho 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) {
1.1.1.2 misho 531: compiler_globals->static_members_table = calloc(compiler_globals->last_static_member, sizeof(zval**));
1.1 misho 532: } else {
1.1.1.2 misho 533: compiler_globals->static_members_table = NULL;
1.1 misho 534: }
1.1.1.2 misho 535: compiler_globals->script_encoding_list = NULL;
1.1 misho 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: }
1.1.1.2 misho 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);
1.1 misho 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;
1.1.1.2 misho 577: #if XPFPA_HAVE_CW
578: EG(saved_fpu_cw) = 0;
579: #endif
580: EG(saved_fpu_cw_ptr) = NULL;
1.1 misho 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:
1.1.1.2 misho 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:
1.1 misho 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;
1.1.1.2 misho 672: #ifndef ZEND_SIGNALS
1.1 misho 673: zend_block_interruptions = utility_functions->block_interruptions;
674: zend_unblock_interruptions = utility_functions->unblock_interruptions;
1.1.1.2 misho 675: #endif
1.1 misho 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:
1.1.1.2 misho 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
1.1 misho 689: zend_compile_file = compile_file;
690: zend_execute = execute;
691: zend_execute_internal = NULL;
1.1.1.2 misho 692: #endif /* HAVE_SYS_SDT_H */
693: zend_compile_string = compile_string;
1.1 misho 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);
1.1.1.2 misho 709: zend_hash_init_ex(GLOBAL_AUTO_GLOBALS_TABLE, 8, NULL, NULL, 1, 0);
1.1 misho 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:
1.1.1.2 misho 747: zend_interned_strings_init(TSRMLS_C);
1.1 misho 748: zend_startup_builtin_functions(TSRMLS_C);
749: zend_register_standard_constants(TSRMLS_C);
1.1.1.2 misho 750: zend_register_auto_global("GLOBALS", sizeof("GLOBALS") - 1, 1, php_auto_globals_create_globals TSRMLS_CC);
1.1 misho 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
1.1.1.3 ! misho 781: zend_encoding **script_encoding_list;
! 782:
1.1 misho 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);
1.1.1.3 ! misho 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: }
1.1 misho 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: {
1.1.1.2 misho 813: #ifdef ZEND_SIGNALS
814: zend_signal_shutdown(TSRMLS_C);
815: #endif
1.1 misho 816: #ifdef ZEND_WIN32
817: zend_shutdown_timeout_thread();
818: #endif
819: zend_destroy_rsrc_list(&EG(persistent_list) TSRMLS_CC);
1.1.1.2 misho 820: zend_destroy_modules();
1.1 misho 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();
1.1.1.2 misho 845:
846: zend_interned_strings_dtor(TSRMLS_C);
1.1 misho 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()
1.1.1.2 misho 973: ZEND_API void zend_message_dispatcher(long message, const void *data TSRMLS_DC) /* {{{ */
1.1 misho 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;
1.1.1.2 misho 1016: const char *error_filename;
1.1 misho 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;
1.1.1.2 misho 1028: zend_stack context_stack;
1.1 misho 1029: TSRMLS_FETCH();
1030:
1.1.1.3 ! misho 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:
1.1 misho 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: va_start(args, format);
1095:
1.1.1.2 misho 1096: #ifdef HAVE_DTRACE
1097: if(DTRACE_ERROR_ENABLED()) {
1098: char *dtrace_error_buffer;
1099: zend_vspprintf(&dtrace_error_buffer, 0, format, args);
1100: DTRACE_ERROR(dtrace_error_buffer, error_filename, error_lineno);
1101: efree(dtrace_error_buffer);
1102: }
1103: #endif /* HAVE_DTRACE */
1104:
1.1 misho 1105: /* if we don't have a user defined error handler */
1106: if (!EG(user_error_handler)
1107: || !(EG(user_error_handler_error_reporting) & type)
1108: || EG(error_handling) != EH_NORMAL) {
1109: zend_error_cb(type, error_filename, error_lineno, format, args);
1110: } else switch (type) {
1111: case E_ERROR:
1112: case E_PARSE:
1113: case E_CORE_ERROR:
1114: case E_CORE_WARNING:
1115: case E_COMPILE_ERROR:
1116: case E_COMPILE_WARNING:
1117: /* The error may not be safe to handle in user-space */
1118: zend_error_cb(type, error_filename, error_lineno, format, args);
1119: break;
1120: default:
1121: /* Handle the error in user space */
1122: ALLOC_INIT_ZVAL(z_error_message);
1123: ALLOC_INIT_ZVAL(z_error_type);
1124: ALLOC_INIT_ZVAL(z_error_filename);
1125: ALLOC_INIT_ZVAL(z_error_lineno);
1126: ALLOC_INIT_ZVAL(z_context);
1127:
1128: /* va_copy() is __va_copy() in old gcc versions.
1129: * According to the autoconf manual, using
1130: * memcpy(&dst, &src, sizeof(va_list))
1131: * gives maximum portability. */
1132: #ifndef va_copy
1133: # ifdef __va_copy
1134: # define va_copy(dest, src) __va_copy((dest), (src))
1135: # else
1136: # define va_copy(dest, src) memcpy(&(dest), &(src), sizeof(va_list))
1137: # endif
1138: #endif
1139: va_copy(usr_copy, args);
1140: Z_STRLEN_P(z_error_message) = zend_vspprintf(&Z_STRVAL_P(z_error_message), 0, format, usr_copy);
1141: #ifdef va_copy
1142: va_end(usr_copy);
1143: #endif
1144: Z_TYPE_P(z_error_message) = IS_STRING;
1145:
1146: Z_LVAL_P(z_error_type) = type;
1147: Z_TYPE_P(z_error_type) = IS_LONG;
1148:
1149: if (error_filename) {
1150: ZVAL_STRING(z_error_filename, error_filename, 1);
1151: }
1152:
1153: Z_LVAL_P(z_error_lineno) = error_lineno;
1154: Z_TYPE_P(z_error_lineno) = IS_LONG;
1155:
1156: if (!EG(active_symbol_table)) {
1157: zend_rebuild_symbol_table(TSRMLS_C);
1158: }
1159:
1160: /* during shutdown the symbol table table can be still null */
1161: if (!EG(active_symbol_table)) {
1162: Z_TYPE_P(z_context) = IS_NULL;
1163: } else {
1164: Z_ARRVAL_P(z_context) = EG(active_symbol_table);
1165: Z_TYPE_P(z_context) = IS_ARRAY;
1166: zval_copy_ctor(z_context);
1167: }
1168:
1169: params = (zval ***) emalloc(sizeof(zval **)*5);
1170: params[0] = &z_error_type;
1171: params[1] = &z_error_message;
1172: params[2] = &z_error_filename;
1173: params[3] = &z_error_lineno;
1174: params[4] = &z_context;
1175:
1176: orig_user_error_handler = EG(user_error_handler);
1177: EG(user_error_handler) = NULL;
1178:
1179: /* User error handler may include() additinal PHP files.
1180: * If an error was generated during comilation PHP will compile
1181: * such scripts recursivly, but some CG() variables may be
1182: * inconsistent. */
1183:
1184: in_compilation = zend_is_compiling(TSRMLS_C);
1185: if (in_compilation) {
1186: saved_class_entry = CG(active_class_entry);
1187: CG(active_class_entry) = NULL;
1188: SAVE_STACK(bp_stack);
1189: SAVE_STACK(function_call_stack);
1190: SAVE_STACK(switch_cond_stack);
1191: SAVE_STACK(foreach_copy_stack);
1192: SAVE_STACK(object_stack);
1193: SAVE_STACK(declare_stack);
1194: SAVE_STACK(list_stack);
1.1.1.2 misho 1195: SAVE_STACK(context_stack);
1.1 misho 1196: }
1197:
1198: if (call_user_function_ex(CG(function_table), NULL, orig_user_error_handler, &retval, 5, params, 1, NULL TSRMLS_CC) == SUCCESS) {
1199: if (retval) {
1200: if (Z_TYPE_P(retval) == IS_BOOL && Z_LVAL_P(retval) == 0) {
1201: zend_error_cb(type, error_filename, error_lineno, format, args);
1202: }
1203: zval_ptr_dtor(&retval);
1204: }
1205: } else if (!EG(exception)) {
1206: /* The user error handler failed, use built-in error handler */
1207: zend_error_cb(type, error_filename, error_lineno, format, args);
1208: }
1209:
1210: if (in_compilation) {
1211: CG(active_class_entry) = saved_class_entry;
1212: RESTORE_STACK(bp_stack);
1213: RESTORE_STACK(function_call_stack);
1214: RESTORE_STACK(switch_cond_stack);
1215: RESTORE_STACK(foreach_copy_stack);
1216: RESTORE_STACK(object_stack);
1217: RESTORE_STACK(declare_stack);
1218: RESTORE_STACK(list_stack);
1.1.1.2 misho 1219: RESTORE_STACK(context_stack);
1.1 misho 1220: }
1221:
1222: if (!EG(user_error_handler)) {
1223: EG(user_error_handler) = orig_user_error_handler;
1224: }
1225: else {
1226: zval_ptr_dtor(&orig_user_error_handler);
1227: }
1228:
1229: efree(params);
1230: zval_ptr_dtor(&z_error_message);
1231: zval_ptr_dtor(&z_error_type);
1232: zval_ptr_dtor(&z_error_filename);
1233: zval_ptr_dtor(&z_error_lineno);
1234: zval_ptr_dtor(&z_context);
1235: break;
1236: }
1237:
1238: va_end(args);
1239:
1240: if (type == E_PARSE) {
1.1.1.3 ! misho 1241: /* eval() errors do not affect exit_status */
! 1242: if (!(EG(current_execute_data) &&
! 1243: EG(current_execute_data)->opline &&
! 1244: EG(current_execute_data)->opline->opcode == ZEND_INCLUDE_OR_EVAL &&
! 1245: EG(current_execute_data)->opline->extended_value == ZEND_EVAL)) {
! 1246: EG(exit_status) = 255;
! 1247: }
1.1 misho 1248: zend_init_compiler_data_structures(TSRMLS_C);
1249: }
1250: }
1251: /* }}} */
1252:
1253: #if defined(__GNUC__) && __GNUC__ >= 3 && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) && !defined(__osf__)
1254: void zend_error_noreturn(int type, const char *format, ...) __attribute__ ((alias("zend_error"),noreturn));
1255: #endif
1256:
1257: ZEND_API void zend_output_debug_string(zend_bool trigger_break, const char *format, ...) /* {{{ */
1258: {
1259: #if ZEND_DEBUG
1260: va_list args;
1261:
1262: va_start(args, format);
1263: # ifdef ZEND_WIN32
1264: {
1265: char output_buf[1024];
1266:
1267: vsnprintf(output_buf, 1024, format, args);
1268: OutputDebugString(output_buf);
1269: OutputDebugString("\n");
1270: if (trigger_break && IsDebuggerPresent()) {
1271: DebugBreak();
1272: }
1273: }
1274: # else
1275: vfprintf(stderr, format, args);
1276: fprintf(stderr, "\n");
1277: # endif
1278: va_end(args);
1279: #endif
1280: }
1281: /* }}} */
1282:
1283: ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval **retval, int file_count, ...) /* {{{ */
1284: {
1285: va_list files;
1286: int i;
1287: zend_file_handle *file_handle;
1288: zend_op_array *orig_op_array = EG(active_op_array);
1289: zval **orig_retval_ptr_ptr = EG(return_value_ptr_ptr);
1.1.1.3 ! misho 1290: long orig_interactive = CG(interactive);
1.1 misho 1291:
1292: va_start(files, file_count);
1293: for (i = 0; i < file_count; i++) {
1294: file_handle = va_arg(files, zend_file_handle *);
1295: if (!file_handle) {
1296: continue;
1297: }
1.1.1.3 ! misho 1298:
! 1299: if (orig_interactive) {
! 1300: if (file_handle->filename[0] != '-' || file_handle->filename[1]) {
! 1301: CG(interactive) = 0;
! 1302: } else {
! 1303: CG(interactive) = 1;
! 1304: }
! 1305: }
! 1306:
1.1 misho 1307: EG(active_op_array) = zend_compile_file(file_handle, type TSRMLS_CC);
1308: if (file_handle->opened_path) {
1309: int dummy = 1;
1310: zend_hash_add(&EG(included_files), file_handle->opened_path, strlen(file_handle->opened_path) + 1, (void *)&dummy, sizeof(int), NULL);
1311: }
1312: zend_destroy_file_handle(file_handle TSRMLS_CC);
1313: if (EG(active_op_array)) {
1314: EG(return_value_ptr_ptr) = retval ? retval : NULL;
1315: zend_execute(EG(active_op_array) TSRMLS_CC);
1316: zend_exception_restore(TSRMLS_C);
1317: if (EG(exception)) {
1318: if (EG(user_exception_handler)) {
1319: zval *orig_user_exception_handler;
1320: zval **params[1], *retval2, *old_exception;
1321: old_exception = EG(exception);
1322: EG(exception) = NULL;
1323: params[0] = &old_exception;
1324: orig_user_exception_handler = EG(user_exception_handler);
1325: if (call_user_function_ex(CG(function_table), NULL, orig_user_exception_handler, &retval2, 1, params, 1, NULL TSRMLS_CC) == SUCCESS) {
1326: if (retval2 != NULL) {
1327: zval_ptr_dtor(&retval2);
1328: }
1329: if (EG(exception)) {
1330: zval_ptr_dtor(&EG(exception));
1331: EG(exception) = NULL;
1332: }
1333: zval_ptr_dtor(&old_exception);
1334: } else {
1335: EG(exception) = old_exception;
1336: zend_exception_error(EG(exception), E_ERROR TSRMLS_CC);
1337: }
1338: } else {
1339: zend_exception_error(EG(exception), E_ERROR TSRMLS_CC);
1340: }
1341: }
1342: destroy_op_array(EG(active_op_array) TSRMLS_CC);
1343: efree(EG(active_op_array));
1344: } else if (type==ZEND_REQUIRE) {
1345: va_end(files);
1346: EG(active_op_array) = orig_op_array;
1347: EG(return_value_ptr_ptr) = orig_retval_ptr_ptr;
1.1.1.3 ! misho 1348: CG(interactive) = orig_interactive;
1.1 misho 1349: return FAILURE;
1350: }
1351: }
1352: va_end(files);
1353: EG(active_op_array) = orig_op_array;
1354: EG(return_value_ptr_ptr) = orig_retval_ptr_ptr;
1.1.1.3 ! misho 1355: CG(interactive) = orig_interactive;
1.1 misho 1356:
1357: return SUCCESS;
1358: }
1359: /* }}} */
1360:
1361: #define COMPILED_STRING_DESCRIPTION_FORMAT "%s(%d) : %s"
1362:
1363: ZEND_API char *zend_make_compiled_string_description(const char *name TSRMLS_DC) /* {{{ */
1364: {
1.1.1.2 misho 1365: const char *cur_filename;
1.1 misho 1366: int cur_lineno;
1367: char *compiled_string_description;
1368:
1369: if (zend_is_compiling(TSRMLS_C)) {
1370: cur_filename = zend_get_compiled_filename(TSRMLS_C);
1371: cur_lineno = zend_get_compiled_lineno(TSRMLS_C);
1372: } else if (zend_is_executing(TSRMLS_C)) {
1373: cur_filename = zend_get_executed_filename(TSRMLS_C);
1374: cur_lineno = zend_get_executed_lineno(TSRMLS_C);
1375: } else {
1376: cur_filename = "Unknown";
1377: cur_lineno = 0;
1378: }
1379:
1380: zend_spprintf(&compiled_string_description, 0, COMPILED_STRING_DESCRIPTION_FORMAT, cur_filename, cur_lineno, name);
1381: return compiled_string_description;
1382: }
1383: /* }}} */
1384:
1385: void free_estring(char **str_p) /* {{{ */
1386: {
1387: efree(*str_p);
1388: }
1389: /* }}} */
1390:
1391: /*
1392: * Local variables:
1393: * tab-width: 4
1394: * c-basic-offset: 4
1395: * indent-tabs-mode: t
1396: * End:
1397: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>