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