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