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