File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / Zend / zend_execute_API.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Oct 14 08:02:48 2013 UTC (10 years, 8 months ago) by misho
Branches: php, MAIN
CVS tags: v5_4_29p0, v5_4_20p0, v5_4_20, HEAD
v 5.4.20

    1: /*
    2:    +----------------------------------------------------------------------+
    3:    | Zend Engine                                                          |
    4:    +----------------------------------------------------------------------+
    5:    | Copyright (c) 1998-2013 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_execute_API.c,v 1.1.1.4 2013/10/14 08:02:48 misho Exp $ */
   21: 
   22: #include <stdio.h>
   23: #include <signal.h>
   24: 
   25: #include "zend.h"
   26: #include "zend_compile.h"
   27: #include "zend_execute.h"
   28: #include "zend_API.h"
   29: #include "zend_ptr_stack.h"
   30: #include "zend_constants.h"
   31: #include "zend_extensions.h"
   32: #include "zend_exceptions.h"
   33: #include "zend_closures.h"
   34: #include "zend_vm.h"
   35: #include "zend_float.h"
   36: #ifdef HAVE_SYS_TIME_H
   37: #include <sys/time.h>
   38: #endif
   39: 
   40: ZEND_API void (*zend_execute)(zend_op_array *op_array TSRMLS_DC);
   41: ZEND_API void (*zend_execute_internal)(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC);
   42: 
   43: /* true globals */
   44: ZEND_API const zend_fcall_info empty_fcall_info = { 0, NULL, NULL, NULL, NULL, 0, NULL, NULL, 0 };
   45: ZEND_API const zend_fcall_info_cache empty_fcall_info_cache = { 0, NULL, NULL, NULL, NULL };
   46: 
   47: #ifdef ZEND_WIN32
   48: #include <process.h>
   49: static WNDCLASS wc;
   50: static HWND timeout_window;
   51: static HANDLE timeout_thread_event;
   52: static HANDLE timeout_thread_handle;
   53: static DWORD timeout_thread_id;
   54: static int timeout_thread_initialized=0;
   55: #endif
   56: 
   57: #if 0&&ZEND_DEBUG
   58: static void (*original_sigsegv_handler)(int);
   59: static void zend_handle_sigsegv(int dummy) /* {{{ */
   60: {
   61: 	fflush(stdout);
   62: 	fflush(stderr);
   63: 	if (original_sigsegv_handler == zend_handle_sigsegv) {
   64: 		signal(SIGSEGV, original_sigsegv_handler);
   65: 	} else {
   66: 		signal(SIGSEGV, SIG_DFL);
   67: 	}
   68: 	{
   69: 		TSRMLS_FETCH();
   70: 
   71: 		fprintf(stderr, "SIGSEGV caught on opcode %d on opline %d of %s() at %s:%d\n\n",
   72: 				active_opline->opcode,
   73: 				active_opline-EG(active_op_array)->opcodes,
   74: 				get_active_function_name(TSRMLS_C),
   75: 				zend_get_executed_filename(TSRMLS_C),
   76: 				zend_get_executed_lineno(TSRMLS_C));
   77: /* See http://support.microsoft.com/kb/190351 */
   78: #ifdef PHP_WIN32
   79: 		fflush(stderr);
   80: #endif
   81: 	}
   82: 	if (original_sigsegv_handler!=zend_handle_sigsegv) {
   83: 		original_sigsegv_handler(dummy);
   84: 	}
   85: }
   86: /* }}} */
   87: #endif
   88: 
   89: static void zend_extension_activator(zend_extension *extension TSRMLS_DC) /* {{{ */
   90: {
   91: 	if (extension->activate) {
   92: 		extension->activate();
   93: 	}
   94: }
   95: /* }}} */
   96: 
   97: static void zend_extension_deactivator(zend_extension *extension TSRMLS_DC) /* {{{ */
   98: {
   99: 	if (extension->deactivate) {
  100: 		extension->deactivate();
  101: 	}
  102: }
  103: /* }}} */
  104: 
  105: static int clean_non_persistent_function(zend_function *function TSRMLS_DC) /* {{{ */
  106: {
  107: 	return (function->type == ZEND_INTERNAL_FUNCTION) ? ZEND_HASH_APPLY_STOP : ZEND_HASH_APPLY_REMOVE;
  108: }
  109: /* }}} */
  110: 
  111: static int clean_non_persistent_function_full(zend_function *function TSRMLS_DC) /* {{{ */
  112: {
  113: 	return (function->type == ZEND_INTERNAL_FUNCTION) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE;
  114: }
  115: /* }}} */
  116: 
  117: static int clean_non_persistent_class(zend_class_entry **ce TSRMLS_DC) /* {{{ */
  118: {
  119: 	return ((*ce)->type == ZEND_INTERNAL_CLASS) ? ZEND_HASH_APPLY_STOP : ZEND_HASH_APPLY_REMOVE;
  120: }
  121: /* }}} */
  122: 
  123: static int clean_non_persistent_class_full(zend_class_entry **ce TSRMLS_DC) /* {{{ */
  124: {
  125: 	return ((*ce)->type == ZEND_INTERNAL_CLASS) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE;
  126: }
  127: /* }}} */
  128: 
  129: void init_executor(TSRMLS_D) /* {{{ */
  130: {
  131: 	zend_init_fpu(TSRMLS_C);
  132: 
  133: 	INIT_ZVAL(EG(uninitialized_zval));
  134: 	/* trick to make uninitialized_zval never be modified, passed by ref, etc. */
  135: 	Z_ADDREF(EG(uninitialized_zval));
  136: 	INIT_ZVAL(EG(error_zval));
  137: 	EG(uninitialized_zval_ptr)=&EG(uninitialized_zval);
  138: 	EG(error_zval_ptr)=&EG(error_zval);
  139: 	zend_ptr_stack_init(&EG(arg_types_stack));
  140: /* destroys stack frame, therefore makes core dumps worthless */
  141: #if 0&&ZEND_DEBUG
  142: 	original_sigsegv_handler = signal(SIGSEGV, zend_handle_sigsegv);
  143: #endif
  144: 	EG(return_value_ptr_ptr) = NULL;
  145: 
  146: 	EG(symtable_cache_ptr) = EG(symtable_cache) - 1;
  147: 	EG(symtable_cache_limit) = EG(symtable_cache) + SYMTABLE_CACHE_SIZE - 1;
  148: 	EG(no_extensions) = 0;
  149: 
  150: 	EG(function_table) = CG(function_table);
  151: 	EG(class_table) = CG(class_table);
  152: 
  153: 	EG(in_execution) = 0;
  154: 	EG(in_autoload) = NULL;
  155: 	EG(autoload_func) = NULL;
  156: 	EG(error_handling) = EH_NORMAL;
  157: 
  158: 	zend_vm_stack_init(TSRMLS_C);
  159: 	zend_vm_stack_push((void *) NULL TSRMLS_CC);
  160: 
  161: 	zend_hash_init(&EG(symbol_table), 50, NULL, ZVAL_PTR_DTOR, 0);
  162: 	EG(active_symbol_table) = &EG(symbol_table);
  163: 
  164: 	zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_activator TSRMLS_CC);
  165: 	EG(opline_ptr) = NULL;
  166: 
  167: 	zend_hash_init(&EG(included_files), 5, NULL, NULL, 0);
  168: 
  169: 	EG(ticks_count) = 0;
  170: 
  171: 	EG(user_error_handler) = NULL;
  172: 
  173: 	EG(current_execute_data) = NULL;
  174: 
  175: 	zend_stack_init(&EG(user_error_handlers_error_reporting));
  176: 	zend_ptr_stack_init(&EG(user_error_handlers));
  177: 	zend_ptr_stack_init(&EG(user_exception_handlers));
  178: 
  179: 	zend_objects_store_init(&EG(objects_store), 1024);
  180: 
  181: 	EG(full_tables_cleanup) = 0;
  182: #ifdef ZEND_WIN32
  183: 	EG(timed_out) = 0;
  184: #endif
  185: 
  186: 	EG(exception) = NULL;
  187: 	EG(prev_exception) = NULL;
  188: 
  189: 	EG(scope) = NULL;
  190: 	EG(called_scope) = NULL;
  191: 
  192: 	EG(This) = NULL;
  193: 
  194: 	EG(active_op_array) = NULL;
  195: 
  196: 	EG(active) = 1;
  197: 	EG(start_op) = NULL;
  198: }
  199: /* }}} */
  200: 
  201: static int zval_call_destructor(zval **zv TSRMLS_DC) /* {{{ */
  202: {
  203: 	if (Z_TYPE_PP(zv) == IS_OBJECT && Z_REFCOUNT_PP(zv) == 1) {
  204: 		return ZEND_HASH_APPLY_REMOVE;
  205: 	} else {
  206: 		return ZEND_HASH_APPLY_KEEP;
  207: 	}
  208: }
  209: /* }}} */
  210: 
  211: void shutdown_destructors(TSRMLS_D) /* {{{ */
  212: {
  213: 	zend_try {
  214: 		int symbols;
  215: 		do {
  216: 			symbols = zend_hash_num_elements(&EG(symbol_table));
  217: 			zend_hash_reverse_apply(&EG(symbol_table), (apply_func_t) zval_call_destructor TSRMLS_CC);
  218: 		} while (symbols != zend_hash_num_elements(&EG(symbol_table)));
  219: 		zend_objects_store_call_destructors(&EG(objects_store) TSRMLS_CC);
  220: 	} zend_catch {
  221: 		/* if we couldn't destruct cleanly, mark all objects as destructed anyway */
  222: 		zend_objects_store_mark_destructed(&EG(objects_store) TSRMLS_CC);
  223: 	} zend_end_try();
  224: }
  225: /* }}} */
  226: 
  227: void shutdown_executor(TSRMLS_D) /* {{{ */
  228: {
  229: 	zend_try {
  230: 
  231: /* Removed because this can not be safely done, e.g. in this situation:
  232:    Object 1 creates object 2
  233:    Object 3 holds reference to object 2.
  234:    Now when 1 and 2 are destroyed, 3 can still access 2 in its destructor, with
  235:    very problematic results */
  236: /* 		zend_objects_store_call_destructors(&EG(objects_store) TSRMLS_CC); */
  237: 
  238: /* Moved after symbol table cleaners, because  some of the cleaners can call
  239:    destructors, which would use EG(symtable_cache_ptr) and thus leave leaks */
  240: /*		while (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
  241: 			zend_hash_destroy(*EG(symtable_cache_ptr));
  242: 			efree(*EG(symtable_cache_ptr));
  243: 			EG(symtable_cache_ptr)--;
  244: 		}
  245: */
  246: 		zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_deactivator TSRMLS_CC);
  247: 		zend_hash_graceful_reverse_destroy(&EG(symbol_table));
  248: 	} zend_end_try();
  249: 
  250: 	zend_try {
  251: 		zval *zeh;
  252: 		/* remove error handlers before destroying classes and functions,
  253: 		 * so that if handler used some class, crash would not happen */
  254: 		if (EG(user_error_handler)) {
  255: 			zeh = EG(user_error_handler);
  256: 			EG(user_error_handler) = NULL;
  257: 			zval_ptr_dtor(&zeh);
  258: 		}
  259: 
  260: 		if (EG(user_exception_handler)) {
  261: 			zeh = EG(user_exception_handler);
  262: 			EG(user_exception_handler) = NULL;
  263: 			zval_ptr_dtor(&zeh);
  264: 		}
  265: 
  266: 		zend_stack_destroy(&EG(user_error_handlers_error_reporting));
  267: 		zend_stack_init(&EG(user_error_handlers_error_reporting));
  268: 		zend_ptr_stack_clean(&EG(user_error_handlers), ZVAL_DESTRUCTOR, 1);
  269: 		zend_ptr_stack_clean(&EG(user_exception_handlers), ZVAL_DESTRUCTOR, 1);
  270: 	} zend_end_try();
  271: 
  272: 	zend_try {
  273: 		/* Cleanup static data for functions and arrays.
  274: 		 * We need a separate cleanup stage because of the following problem:
  275: 		 * Suppose we destroy class X, which destroys the class's function table,
  276: 		 * and in the function table we have function foo() that has static $bar.
  277: 		 * Now if an object of class X is assigned to $bar, its destructor will be
  278: 		 * called and will fail since X's function table is in mid-destruction.
  279: 		 * So we want first of all to clean up all data and then move to tables destruction.
  280: 		 * Note that only run-time accessed data need to be cleaned up, pre-defined data can
  281: 		 * not contain objects and thus are not probelmatic */
  282: 		if (EG(full_tables_cleanup)) {
  283: 			zend_hash_apply(EG(function_table), (apply_func_t) zend_cleanup_function_data_full TSRMLS_CC);
  284: 			zend_hash_apply(EG(class_table), (apply_func_t) zend_cleanup_class_data TSRMLS_CC);
  285: 		} else {
  286: 			zend_hash_reverse_apply(EG(function_table), (apply_func_t) zend_cleanup_function_data TSRMLS_CC);
  287: 			zend_hash_reverse_apply(EG(class_table), (apply_func_t) zend_cleanup_user_class_data TSRMLS_CC);
  288: 			zend_cleanup_internal_classes(TSRMLS_C);
  289: 		}
  290: 	} zend_end_try();
  291: 
  292: 	zend_try {
  293: 		zend_vm_stack_destroy(TSRMLS_C);
  294: 
  295: 		zend_objects_store_free_object_storage(&EG(objects_store) TSRMLS_CC);
  296: 
  297: 		/* Destroy all op arrays */
  298: 		if (EG(full_tables_cleanup)) {
  299: 			zend_hash_reverse_apply(EG(function_table), (apply_func_t) clean_non_persistent_function_full TSRMLS_CC);
  300: 			zend_hash_reverse_apply(EG(class_table), (apply_func_t) clean_non_persistent_class_full TSRMLS_CC);
  301: 		} else {
  302: 			zend_hash_reverse_apply(EG(function_table), (apply_func_t) clean_non_persistent_function TSRMLS_CC);
  303: 			zend_hash_reverse_apply(EG(class_table), (apply_func_t) clean_non_persistent_class TSRMLS_CC);
  304: 		}
  305: 
  306: 		while (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
  307: 			zend_hash_destroy(*EG(symtable_cache_ptr));
  308: 			FREE_HASHTABLE(*EG(symtable_cache_ptr));
  309: 			EG(symtable_cache_ptr)--;
  310: 		}
  311: 	} zend_end_try();
  312: 
  313: 	zend_try {
  314: 		clean_non_persistent_constants(TSRMLS_C);
  315: 	} zend_end_try();
  316: 
  317: 	zend_try {
  318: #if 0&&ZEND_DEBUG
  319: 	signal(SIGSEGV, original_sigsegv_handler);
  320: #endif
  321: 
  322: 		zend_hash_destroy(&EG(included_files));
  323: 
  324: 		zend_ptr_stack_destroy(&EG(arg_types_stack));
  325: 		zend_stack_destroy(&EG(user_error_handlers_error_reporting));
  326: 		zend_ptr_stack_destroy(&EG(user_error_handlers));
  327: 		zend_ptr_stack_destroy(&EG(user_exception_handlers));
  328: 		zend_objects_store_destroy(&EG(objects_store));
  329: 		if (EG(in_autoload)) {
  330: 			zend_hash_destroy(EG(in_autoload));
  331: 			FREE_HASHTABLE(EG(in_autoload));
  332: 		}
  333: 	} zend_end_try();
  334: 
  335: 	zend_shutdown_fpu(TSRMLS_C);
  336: 
  337: 	EG(active) = 0;
  338: }
  339: /* }}} */
  340: 
  341: /* return class name and "::" or "". */
  342: ZEND_API const char *get_active_class_name(const char **space TSRMLS_DC) /* {{{ */
  343: {
  344: 	if (!zend_is_executing(TSRMLS_C)) {
  345: 		if (space) {
  346: 			*space = "";
  347: 		}
  348: 		return "";
  349: 	}
  350: 	switch (EG(current_execute_data)->function_state.function->type) {
  351: 		case ZEND_USER_FUNCTION:
  352: 		case ZEND_INTERNAL_FUNCTION:
  353: 		{
  354: 			zend_class_entry *ce = EG(current_execute_data)->function_state.function->common.scope;
  355: 
  356: 			if (space) {
  357: 				*space = ce ? "::" : "";
  358: 			}
  359: 			return ce ? ce->name : "";
  360: 		}
  361: 		default:
  362: 			if (space) {
  363: 				*space = "";
  364: 			}
  365: 			return "";
  366: 	}
  367: }
  368: /* }}} */
  369: 
  370: ZEND_API const char *get_active_function_name(TSRMLS_D) /* {{{ */
  371: {
  372: 	if (!zend_is_executing(TSRMLS_C)) {
  373: 		return NULL;
  374: 	}
  375: 	switch (EG(current_execute_data)->function_state.function->type) {
  376: 		case ZEND_USER_FUNCTION: {
  377: 				const char *function_name = ((zend_op_array *) EG(current_execute_data)->function_state.function)->function_name;
  378: 
  379: 				if (function_name) {
  380: 					return function_name;
  381: 				} else {
  382: 					return "main";
  383: 				}
  384: 			}
  385: 			break;
  386: 		case ZEND_INTERNAL_FUNCTION:
  387: 			return ((zend_internal_function *) EG(current_execute_data)->function_state.function)->function_name;
  388: 			break;
  389: 		default:
  390: 			return NULL;
  391: 	}
  392: }
  393: /* }}} */
  394: 
  395: ZEND_API const char *zend_get_executed_filename(TSRMLS_D) /* {{{ */
  396: {
  397: 	if (EG(active_op_array)) {
  398: 		return EG(active_op_array)->filename;
  399: 	} else {
  400: 		return "[no active file]";
  401: 	}
  402: }
  403: /* }}} */
  404: 
  405: ZEND_API uint zend_get_executed_lineno(TSRMLS_D) /* {{{ */
  406: {
  407: 	if(EG(exception) && EG(opline_ptr) && active_opline->opcode == ZEND_HANDLE_EXCEPTION && 
  408: 		active_opline->lineno == 0 && EG(opline_before_exception)) {
  409: 		return EG(opline_before_exception)->lineno;
  410: 	}
  411: 	if (EG(opline_ptr)) {
  412: 		return active_opline->lineno;
  413: 	} else {
  414: 		return 0;
  415: 	}
  416: }
  417: /* }}} */
  418: 
  419: ZEND_API zend_bool zend_is_executing(TSRMLS_D) /* {{{ */
  420: {
  421: 	return EG(in_execution);
  422: }
  423: /* }}} */
  424: 
  425: ZEND_API void _zval_ptr_dtor(zval **zval_ptr ZEND_FILE_LINE_DC) /* {{{ */
  426: {
  427: #if DEBUG_ZEND>=2
  428: 	printf("Reducing refcount for %x (%x): %d->%d\n", *zval_ptr, zval_ptr, Z_REFCOUNT_PP(zval_ptr), Z_REFCOUNT_PP(zval_ptr) - 1);
  429: #endif
  430: 	Z_DELREF_PP(zval_ptr);
  431: 	if (Z_REFCOUNT_PP(zval_ptr) == 0) {
  432: 		TSRMLS_FETCH();
  433: 
  434: 		if (*zval_ptr != &EG(uninitialized_zval)) {
  435: 			GC_REMOVE_ZVAL_FROM_BUFFER(*zval_ptr);
  436: 			zval_dtor(*zval_ptr);
  437: 			efree_rel(*zval_ptr);
  438: 		}
  439: 	} else {
  440: 		TSRMLS_FETCH();
  441: 
  442: 		if (Z_REFCOUNT_PP(zval_ptr) == 1) {
  443: 			Z_UNSET_ISREF_PP(zval_ptr);
  444: 		}
  445: 
  446: 		GC_ZVAL_CHECK_POSSIBLE_ROOT(*zval_ptr);
  447: 	}
  448: }
  449: /* }}} */
  450: 
  451: ZEND_API void _zval_internal_ptr_dtor(zval **zval_ptr ZEND_FILE_LINE_DC) /* {{{ */
  452: {
  453: #if DEBUG_ZEND>=2
  454: 	printf("Reducing refcount for %x (%x): %d->%d\n", *zval_ptr, zval_ptr, Z_REFCOUNT_PP(zval_ptr), Z_REFCOUNT_PP(zval_ptr) - 1);
  455: #endif
  456: 	Z_DELREF_PP(zval_ptr);
  457: 	if (Z_REFCOUNT_PP(zval_ptr) == 0) {
  458: 		zval_internal_dtor(*zval_ptr);
  459: 		free(*zval_ptr);
  460: 	} else if (Z_REFCOUNT_PP(zval_ptr) == 1) {
  461: 		Z_UNSET_ISREF_PP(zval_ptr);
  462: 	}
  463: }
  464: /* }}} */
  465: 
  466: ZEND_API int zend_is_true(zval *op) /* {{{ */
  467: {
  468: 	return i_zend_is_true(op);
  469: }
  470: /* }}} */
  471: 
  472: #include "../TSRM/tsrm_strtok_r.h"
  473: 
  474: #define IS_VISITED_CONSTANT			IS_CONSTANT_INDEX
  475: #define IS_CONSTANT_VISITED(p)		(Z_TYPE_P(p) & IS_VISITED_CONSTANT)
  476: #define Z_REAL_TYPE_P(p)			(Z_TYPE_P(p) & ~IS_VISITED_CONSTANT)
  477: #define MARK_CONSTANT_VISITED(p)	Z_TYPE_P(p) |= IS_VISITED_CONSTANT
  478: 
  479: static void zval_deep_copy(zval **p)
  480: {
  481: 	zval *value;
  482: 
  483: 	ALLOC_ZVAL(value);
  484: 	*value = **p;
  485: 	Z_TYPE_P(value) &= ~IS_CONSTANT_INDEX;
  486: 	zval_copy_ctor(value);
  487: 	Z_TYPE_P(value) = Z_TYPE_PP(p);
  488: 	INIT_PZVAL(value);
  489: 	*p = value;
  490: }
  491: 
  492: ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *scope TSRMLS_DC) /* {{{ */
  493: {
  494: 	zval *p = *pp;
  495: 	zend_bool inline_change = (zend_bool) (zend_uintptr_t) arg;
  496: 	zval const_value;
  497: 	char *colon;
  498: 
  499: 	if (IS_CONSTANT_VISITED(p)) {
  500: 		zend_error(E_ERROR, "Cannot declare self-referencing constant '%s'", Z_STRVAL_P(p));
  501: 	} else if ((Z_TYPE_P(p) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) {
  502: 		int refcount;
  503: 		zend_uchar is_ref;
  504: 
  505: 		SEPARATE_ZVAL_IF_NOT_REF(pp);
  506: 		p = *pp;
  507: 
  508: 		MARK_CONSTANT_VISITED(p);
  509: 
  510: 		refcount = Z_REFCOUNT_P(p);
  511: 		is_ref = Z_ISREF_P(p);
  512: 
  513: 		if (!zend_get_constant_ex(p->value.str.val, p->value.str.len, &const_value, scope, Z_REAL_TYPE_P(p) TSRMLS_CC)) {
  514: 			char *actual = Z_STRVAL_P(p);
  515: 
  516: 			if ((colon = (char*)zend_memrchr(Z_STRVAL_P(p), ':', Z_STRLEN_P(p)))) {
  517: 				zend_error(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(p));
  518: 				Z_STRLEN_P(p) -= ((colon - Z_STRVAL_P(p)) + 1);
  519: 				if (inline_change) {
  520: 					colon = estrndup(colon, Z_STRLEN_P(p));
  521: 					str_efree(Z_STRVAL_P(p));
  522: 					Z_STRVAL_P(p) = colon;
  523: 				} else {
  524: 					Z_STRVAL_P(p) = colon + 1;
  525: 				}
  526: 			} else {
  527: 				char *save = actual, *slash;
  528: 				int actual_len = Z_STRLEN_P(p);
  529: 				if ((Z_TYPE_P(p) & IS_CONSTANT_UNQUALIFIED) && (slash = (char *)zend_memrchr(actual, '\\', actual_len))) {
  530: 					actual = slash + 1;
  531: 					actual_len -= (actual - Z_STRVAL_P(p));
  532: 					if (inline_change) {
  533: 						actual = estrndup(actual, actual_len);
  534: 						Z_STRVAL_P(p) = actual;
  535: 						Z_STRLEN_P(p) = actual_len;
  536: 					}
  537: 				}
  538: 				if (actual[0] == '\\') {
  539: 					if (inline_change) {
  540: 						memmove(Z_STRVAL_P(p), Z_STRVAL_P(p)+1, Z_STRLEN_P(p));
  541: 						--Z_STRLEN_P(p);
  542: 					} else {
  543: 						++actual;
  544: 					}
  545: 					--actual_len;
  546: 				}
  547: 				if ((Z_TYPE_P(p) & IS_CONSTANT_UNQUALIFIED) == 0) {
  548: 					int fix_save = 0;
  549: 					if (save[0] == '\\') {
  550: 						save++;
  551: 						fix_save = 1;
  552: 					}
  553: 					zend_error(E_ERROR, "Undefined constant '%s'", save);
  554: 					if (fix_save) {
  555: 						save--;
  556: 					}
  557: 					if (inline_change && !IS_INTERNED(save)) {
  558: 						efree(save);
  559: 					}
  560: 					save = NULL;
  561: 				}
  562: 				if (inline_change && save && save != actual && !IS_INTERNED(save)) {
  563: 					efree(save);
  564: 				}
  565: 				zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'",  actual,  actual);
  566: 				p->type = IS_STRING;
  567: 				if (!inline_change) {
  568: 					Z_STRVAL_P(p) = actual;
  569: 					Z_STRLEN_P(p) = actual_len;
  570: 					zval_copy_ctor(p);
  571: 				}
  572: 			}
  573: 		} else {
  574: 			if (inline_change) {
  575: 				STR_FREE(Z_STRVAL_P(p));
  576: 			}
  577: 			*p = const_value;
  578: 		}
  579: 
  580: 		Z_SET_REFCOUNT_P(p, refcount);
  581: 		Z_SET_ISREF_TO_P(p, is_ref);
  582: 	} else if (Z_TYPE_P(p) == IS_CONSTANT_ARRAY) {
  583: 		zval **element, *new_val;
  584: 		char *str_index;
  585: 		uint str_index_len;
  586: 		ulong num_index;
  587: 		int ret;
  588: 
  589: 		SEPARATE_ZVAL_IF_NOT_REF(pp);
  590: 		p = *pp;
  591: 		Z_TYPE_P(p) = IS_ARRAY;
  592: 
  593: 		if (!inline_change) {
  594: 			zval *tmp;
  595: 			HashTable *tmp_ht = NULL;
  596: 
  597: 			ALLOC_HASHTABLE(tmp_ht);
  598: 			zend_hash_init(tmp_ht, zend_hash_num_elements(Z_ARRVAL_P(p)), NULL, ZVAL_PTR_DTOR, 0);
  599: 			zend_hash_copy(tmp_ht, Z_ARRVAL_P(p), (copy_ctor_func_t) zval_deep_copy, (void *) &tmp, sizeof(zval *));
  600: 			Z_ARRVAL_P(p) = tmp_ht;
  601: 		} 
  602: 
  603: 		/* First go over the array and see if there are any constant indices */
  604: 		zend_hash_internal_pointer_reset(Z_ARRVAL_P(p));
  605: 		while (zend_hash_get_current_data(Z_ARRVAL_P(p), (void **) &element) == SUCCESS) {
  606: 			if (!(Z_TYPE_PP(element) & IS_CONSTANT_INDEX)) {
  607: 				zend_hash_move_forward(Z_ARRVAL_P(p));
  608: 				continue;
  609: 			}
  610: 			Z_TYPE_PP(element) &= ~IS_CONSTANT_INDEX;
  611: 			if (zend_hash_get_current_key_ex(Z_ARRVAL_P(p), &str_index, &str_index_len, &num_index, 0, NULL) != HASH_KEY_IS_STRING) {
  612: 				zend_hash_move_forward(Z_ARRVAL_P(p));
  613: 				continue;
  614: 			}
  615: 			if (!zend_get_constant_ex(str_index, str_index_len - 3, &const_value, scope, str_index[str_index_len - 2] TSRMLS_CC)) {
  616: 				char *actual;
  617: 				const char *save = str_index;
  618: 				if ((colon = (char*)zend_memrchr(str_index, ':', str_index_len - 3))) {
  619: 					zend_error(E_ERROR, "Undefined class constant '%s'", str_index);
  620: 					str_index_len -= ((colon - str_index) + 1);
  621: 					str_index = colon;
  622: 				} else {
  623: 					if (str_index[str_index_len - 2] & IS_CONSTANT_UNQUALIFIED) {
  624: 						if ((actual = (char *)zend_memrchr(str_index, '\\', str_index_len - 3))) {
  625: 							actual++;
  626: 							str_index_len -= (actual - str_index);
  627: 							str_index = actual;
  628: 						}
  629: 					}
  630: 					if (str_index[0] == '\\') {
  631: 						++str_index;
  632: 						--str_index_len;
  633: 					}
  634: 					if (save[0] == '\\') {
  635: 						++save;
  636: 					}
  637: 					if ((str_index[str_index_len - 2] & IS_CONSTANT_UNQUALIFIED) == 0) {
  638: 						zend_error(E_ERROR, "Undefined constant '%s'", save);
  639: 					}
  640: 					zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'",	str_index, str_index);
  641: 				}
  642: 				ZVAL_STRINGL(&const_value, str_index, str_index_len-3, 1);
  643: 			}
  644: 
  645: 			if (Z_REFCOUNT_PP(element) > 1) {
  646: 				ALLOC_ZVAL(new_val);
  647: 				*new_val = **element;
  648: 				zval_copy_ctor(new_val);
  649: 				Z_SET_REFCOUNT_P(new_val, 1);
  650: 				Z_UNSET_ISREF_P(new_val);
  651: 
  652: 				/* preserve this bit for inheritance */
  653: 				Z_TYPE_PP(element) |= IS_CONSTANT_INDEX;
  654: 				zval_ptr_dtor(element);
  655: 				*element = new_val;
  656: 			}
  657: 
  658: 			switch (Z_TYPE(const_value)) {
  659: 				case IS_STRING:
  660: 					ret = zend_symtable_update_current_key(Z_ARRVAL_P(p), Z_STRVAL(const_value), Z_STRLEN(const_value) + 1, HASH_UPDATE_KEY_IF_BEFORE);
  661: 					break;
  662: 				case IS_BOOL:
  663: 				case IS_LONG:
  664: 					ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, Z_LVAL(const_value), HASH_UPDATE_KEY_IF_BEFORE, NULL);
  665: 					break;
  666: 				case IS_DOUBLE:
  667: 					ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, zend_dval_to_lval(Z_DVAL(const_value)), HASH_UPDATE_KEY_IF_BEFORE, NULL);
  668: 					break;
  669: 				case IS_NULL:
  670: 					ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_STRING, "", 1, 0, HASH_UPDATE_KEY_IF_BEFORE, NULL);
  671: 					break;
  672: 				default:
  673: 					ret = SUCCESS;
  674: 					break;
  675: 			}
  676: 			if (ret == SUCCESS) {
  677: 				zend_hash_move_forward(Z_ARRVAL_P(p));
  678: 			}
  679: 			zval_dtor(&const_value);
  680: 		}
  681: 		zend_hash_apply_with_argument(Z_ARRVAL_P(p), (apply_func_arg_t) zval_update_constant_inline_change, (void *) scope TSRMLS_CC);
  682: 		zend_hash_internal_pointer_reset(Z_ARRVAL_P(p));
  683: 	}
  684: 	return 0;
  685: }
  686: /* }}} */
  687: 
  688: ZEND_API int zval_update_constant_inline_change(zval **pp, void *scope TSRMLS_DC) /* {{{ */
  689: {
  690: 	return zval_update_constant_ex(pp, (void*)1, scope TSRMLS_CC);
  691: }
  692: /* }}} */
  693: 
  694: ZEND_API int zval_update_constant_no_inline_change(zval **pp, void *scope TSRMLS_DC) /* {{{ */
  695: {
  696: 	return zval_update_constant_ex(pp, (void*)0, scope TSRMLS_CC);
  697: }
  698: /* }}} */
  699: 
  700: ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC) /* {{{ */
  701: {
  702: 	return zval_update_constant_ex(pp, arg, NULL TSRMLS_CC);
  703: }
  704: /* }}} */
  705: 
  706: int call_user_function(HashTable *function_table, zval **object_pp, zval *function_name, zval *retval_ptr, zend_uint param_count, zval *params[] TSRMLS_DC) /* {{{ */
  707: {
  708: 	zval ***params_array;
  709: 	zend_uint i;
  710: 	int ex_retval;
  711: 	zval *local_retval_ptr = NULL;
  712: 
  713: 	if (param_count) {
  714: 		params_array = (zval ***) emalloc(sizeof(zval **)*param_count);
  715: 		for (i=0; i<param_count; i++) {
  716: 			params_array[i] = &params[i];
  717: 		}
  718: 	} else {
  719: 		params_array = NULL;
  720: 	}
  721: 	ex_retval = call_user_function_ex(function_table, object_pp, function_name, &local_retval_ptr, param_count, params_array, 1, NULL TSRMLS_CC);
  722: 	if (local_retval_ptr) {
  723: 		COPY_PZVAL_TO_ZVAL(*retval_ptr, local_retval_ptr);
  724: 	} else {
  725: 		INIT_ZVAL(*retval_ptr);
  726: 	}
  727: 	if (params_array) {
  728: 		efree(params_array);
  729: 	}
  730: 	return ex_retval;
  731: }
  732: /* }}} */
  733: 
  734: int call_user_function_ex(HashTable *function_table, zval **object_pp, zval *function_name, zval **retval_ptr_ptr, zend_uint param_count, zval **params[], int no_separation, HashTable *symbol_table TSRMLS_DC) /* {{{ */
  735: {
  736: 	zend_fcall_info fci;
  737: 
  738: 	fci.size = sizeof(fci);
  739: 	fci.function_table = function_table;
  740: 	fci.object_ptr = object_pp ? *object_pp : NULL;
  741: 	fci.function_name = function_name;
  742: 	fci.retval_ptr_ptr = retval_ptr_ptr;
  743: 	fci.param_count = param_count;
  744: 	fci.params = params;
  745: 	fci.no_separation = (zend_bool) no_separation;
  746: 	fci.symbol_table = symbol_table;
  747: 
  748: 	return zend_call_function(&fci, NULL TSRMLS_CC);
  749: }
  750: /* }}} */
  751: 
  752: int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TSRMLS_DC) /* {{{ */
  753: {
  754: 	zend_uint i;
  755: 	zval **original_return_value;
  756: 	HashTable *calling_symbol_table;
  757: 	zend_op_array *original_op_array;
  758: 	zend_op **original_opline_ptr;
  759: 	zend_class_entry *current_scope;
  760: 	zend_class_entry *current_called_scope;
  761: 	zend_class_entry *calling_scope = NULL;
  762: 	zend_class_entry *called_scope = NULL;
  763: 	zval *current_this;
  764: 	zend_execute_data execute_data;
  765: 	zend_fcall_info_cache fci_cache_local;
  766: 
  767: 	*fci->retval_ptr_ptr = NULL;
  768: 
  769: 	if (!EG(active)) {
  770: 		return FAILURE; /* executor is already inactive */
  771: 	}
  772: 
  773: 	if (EG(exception)) {
  774: 		return FAILURE; /* we would result in an instable executor otherwise */
  775: 	}
  776: 
  777: 	switch (fci->size) {
  778: 		case sizeof(zend_fcall_info):
  779: 			break; /* nothing to do currently */
  780: 		default:
  781: 			zend_error(E_ERROR, "Corrupted fcall_info provided to zend_call_function()");
  782: 			break;
  783: 	}
  784: 
  785: 	/* Initialize execute_data */
  786: 	if (EG(current_execute_data)) {
  787: 		execute_data = *EG(current_execute_data);
  788: 		EX(op_array) = NULL;
  789: 		EX(opline) = NULL;
  790: 		EX(object) = NULL;
  791: 	} else {
  792: 		/* This only happens when we're called outside any execute()'s
  793: 		 * It shouldn't be strictly necessary to NULL execute_data out,
  794: 		 * but it may make bugs easier to spot
  795: 		 */
  796: 		memset(&execute_data, 0, sizeof(zend_execute_data));
  797: 	}
  798: 
  799: 	if (!fci_cache || !fci_cache->initialized) {
  800: 		char *callable_name;
  801: 		char *error = NULL;
  802: 
  803: 		if (!fci_cache) {
  804: 			fci_cache = &fci_cache_local;
  805: 		}
  806: 
  807: 		if (!zend_is_callable_ex(fci->function_name, fci->object_ptr, IS_CALLABLE_CHECK_SILENT, &callable_name, NULL, fci_cache, &error TSRMLS_CC)) {
  808: 			if (error) {
  809: 				zend_error(E_WARNING, "Invalid callback %s, %s", callable_name, error);
  810: 				efree(error);
  811: 			}
  812: 			if (callable_name) {
  813: 				efree(callable_name);
  814: 			}
  815: 			return FAILURE;
  816: 		} else if (error) {
  817: 			/* Capitalize the first latter of the error message */
  818: 			if (error[0] >= 'a' && error[0] <= 'z') {
  819: 				error[0] += ('A' - 'a');
  820: 			}
  821: 			zend_error(E_STRICT, "%s", error);
  822: 			efree(error);
  823: 		}
  824: 		efree(callable_name);
  825: 	}
  826: 
  827: 	EX(function_state).function = fci_cache->function_handler;
  828: 	calling_scope = fci_cache->calling_scope;
  829: 	called_scope = fci_cache->called_scope;
  830: 	fci->object_ptr = fci_cache->object_ptr;
  831: 	EX(object) = fci->object_ptr;
  832: 	if (fci->object_ptr && Z_TYPE_P(fci->object_ptr) == IS_OBJECT &&
  833: 	    (!EG(objects_store).object_buckets || !EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(fci->object_ptr)].valid)) {
  834: 		return FAILURE;
  835: 	}
  836: 
  837: 	if (EX(function_state).function->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) {
  838: 		if (EX(function_state).function->common.fn_flags & ZEND_ACC_ABSTRACT) {
  839: 			zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", EX(function_state).function->common.scope->name, EX(function_state).function->common.function_name);
  840: 		}
  841: 		if (EX(function_state).function->common.fn_flags & ZEND_ACC_DEPRECATED) {
  842:  			zend_error(E_DEPRECATED, "Function %s%s%s() is deprecated",
  843: 				EX(function_state).function->common.scope ? EX(function_state).function->common.scope->name : "",
  844: 				EX(function_state).function->common.scope ? "::" : "",
  845: 				EX(function_state).function->common.function_name);
  846: 		}
  847: 	}
  848: 
  849: 	ZEND_VM_STACK_GROW_IF_NEEDED(fci->param_count + 1);
  850: 
  851: 	for (i=0; i<fci->param_count; i++) {
  852: 		zval *param;
  853: 
  854: 		if (ARG_SHOULD_BE_SENT_BY_REF(EX(function_state).function, i + 1)) {
  855: 			if (!PZVAL_IS_REF(*fci->params[i]) && Z_REFCOUNT_PP(fci->params[i]) > 1) {
  856: 				zval *new_zval;
  857: 
  858: 				if (fci->no_separation &&
  859: 				    !ARG_MAY_BE_SENT_BY_REF(EX(function_state).function, i + 1)) {
  860: 					if (i || UNEXPECTED(ZEND_VM_STACK_ELEMETS(EG(argument_stack)) == (EG(argument_stack)->top))) {
  861: 						/* hack to clean up the stack */
  862: 						zend_vm_stack_push_nocheck((void *) (zend_uintptr_t)i TSRMLS_CC);
  863: 						zend_vm_stack_clear_multiple(TSRMLS_C);
  864: 					}
  865: 
  866: 					zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given",
  867: 						i+1,
  868: 						EX(function_state).function->common.scope ? EX(function_state).function->common.scope->name : "",
  869: 						EX(function_state).function->common.scope ? "::" : "",
  870: 						EX(function_state).function->common.function_name);
  871: 					return FAILURE;
  872: 				}
  873: 
  874: 				ALLOC_ZVAL(new_zval);
  875: 				*new_zval = **fci->params[i];
  876: 				zval_copy_ctor(new_zval);
  877: 				Z_SET_REFCOUNT_P(new_zval, 1);
  878: 				Z_DELREF_PP(fci->params[i]);
  879: 				*fci->params[i] = new_zval;
  880: 			}
  881: 			Z_ADDREF_PP(fci->params[i]);
  882: 			Z_SET_ISREF_PP(fci->params[i]);
  883: 			param = *fci->params[i];
  884: 		} else if (PZVAL_IS_REF(*fci->params[i]) &&
  885: 		           /* don't separate references for __call */
  886: 		           (EX(function_state).function->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) == 0 ) {
  887: 			ALLOC_ZVAL(param);
  888: 			*param = **(fci->params[i]);
  889: 			INIT_PZVAL(param);
  890: 			zval_copy_ctor(param);
  891: 		} else if (*fci->params[i] != &EG(uninitialized_zval)) {
  892: 			Z_ADDREF_PP(fci->params[i]);
  893: 			param = *fci->params[i];
  894: 		} else {
  895: 			ALLOC_ZVAL(param);
  896: 			*param = **(fci->params[i]);
  897: 			INIT_PZVAL(param);
  898: 		}
  899: 		zend_vm_stack_push_nocheck(param TSRMLS_CC);
  900: 	}
  901: 
  902: 	EX(function_state).arguments = zend_vm_stack_top(TSRMLS_C);
  903: 	zend_vm_stack_push_nocheck((void*)(zend_uintptr_t)fci->param_count TSRMLS_CC);
  904: 
  905: 	current_scope = EG(scope);
  906: 	EG(scope) = calling_scope;
  907: 
  908: 	current_this = EG(This);
  909: 
  910: 	current_called_scope = EG(called_scope);
  911: 	if (called_scope) {
  912: 		EG(called_scope) = called_scope;
  913: 	} else if (EX(function_state).function->type != ZEND_INTERNAL_FUNCTION) {
  914: 		EG(called_scope) = NULL;
  915: 	}
  916: 
  917: 	if (fci->object_ptr) {
  918: 		if ((EX(function_state).function->common.fn_flags & ZEND_ACC_STATIC)) {
  919: 			EG(This) = NULL;
  920: 		} else {
  921: 			EG(This) = fci->object_ptr;
  922: 
  923: 			if (!PZVAL_IS_REF(EG(This))) {
  924: 				Z_ADDREF_P(EG(This)); /* For $this pointer */
  925: 			} else {
  926: 				zval *this_ptr;
  927: 
  928: 				ALLOC_ZVAL(this_ptr);
  929: 				*this_ptr = *EG(This);
  930: 				INIT_PZVAL(this_ptr);
  931: 				zval_copy_ctor(this_ptr);
  932: 				EG(This) = this_ptr;
  933: 			}
  934: 		}
  935: 	} else {
  936: 		EG(This) = NULL;
  937: 	}
  938: 
  939: 	EX(prev_execute_data) = EG(current_execute_data);
  940: 	EG(current_execute_data) = &execute_data;
  941: 
  942: 	if (EX(function_state).function->type == ZEND_USER_FUNCTION) {
  943: 		calling_symbol_table = EG(active_symbol_table);
  944: 		EG(scope) = EX(function_state).function->common.scope;
  945: 		if (fci->symbol_table) {
  946: 			EG(active_symbol_table) = fci->symbol_table;
  947: 		} else {
  948: 			EG(active_symbol_table) = NULL;
  949: 		}
  950: 
  951: 		original_return_value = EG(return_value_ptr_ptr);
  952: 		original_op_array = EG(active_op_array);
  953: 		EG(return_value_ptr_ptr) = fci->retval_ptr_ptr;
  954: 		EG(active_op_array) = (zend_op_array *) EX(function_state).function;
  955: 		original_opline_ptr = EG(opline_ptr);
  956: 		zend_execute(EG(active_op_array) TSRMLS_CC);
  957: 		if (!fci->symbol_table && EG(active_symbol_table)) {
  958: 			if (EG(symtable_cache_ptr)>=EG(symtable_cache_limit)) {
  959: 				zend_hash_destroy(EG(active_symbol_table));
  960: 				FREE_HASHTABLE(EG(active_symbol_table));
  961: 			} else {
  962: 				/* clean before putting into the cache, since clean
  963: 				   could call dtors, which could use cached hash */
  964: 				zend_hash_clean(EG(active_symbol_table));
  965: 				*(++EG(symtable_cache_ptr)) = EG(active_symbol_table);
  966: 			}
  967: 		}
  968: 		EG(active_symbol_table) = calling_symbol_table;
  969: 		EG(active_op_array) = original_op_array;
  970: 		EG(return_value_ptr_ptr)=original_return_value;
  971: 		EG(opline_ptr) = original_opline_ptr;
  972: 	} else if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) {
  973: 		int call_via_handler = (EX(function_state).function->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0;
  974: 		ALLOC_INIT_ZVAL(*fci->retval_ptr_ptr);
  975: 		if (EX(function_state).function->common.scope) {
  976: 			EG(scope) = EX(function_state).function->common.scope;
  977: 		}
  978: 		((zend_internal_function *) EX(function_state).function)->handler(fci->param_count, *fci->retval_ptr_ptr, fci->retval_ptr_ptr, fci->object_ptr, 1 TSRMLS_CC);
  979: 		/*  We shouldn't fix bad extensions here,
  980: 			because it can break proper ones (Bug #34045)
  981: 		if (!EX(function_state).function->common.return_reference)
  982: 		{
  983: 			INIT_PZVAL(*fci->retval_ptr_ptr);
  984: 		}*/
  985: 		if (EG(exception) && fci->retval_ptr_ptr) {
  986: 			zval_ptr_dtor(fci->retval_ptr_ptr);
  987: 			*fci->retval_ptr_ptr = NULL;
  988: 		}
  989: 
  990: 		if (call_via_handler) {
  991: 			/* We must re-initialize function again */
  992: 			fci_cache->initialized = 0;
  993: 		}
  994: 	} else { /* ZEND_OVERLOADED_FUNCTION */
  995: 		ALLOC_INIT_ZVAL(*fci->retval_ptr_ptr);
  996: 
  997: 		/* Not sure what should be done here if it's a static method */
  998: 		if (fci->object_ptr) {
  999: 			Z_OBJ_HT_P(fci->object_ptr)->call_method(EX(function_state).function->common.function_name, fci->param_count, *fci->retval_ptr_ptr, fci->retval_ptr_ptr, fci->object_ptr, 1 TSRMLS_CC);
 1000: 		} else {
 1001: 			zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
 1002: 		}
 1003: 
 1004: 		if (EX(function_state).function->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
 1005: 			efree((char*)EX(function_state).function->common.function_name);
 1006: 		}
 1007: 		efree(EX(function_state).function);
 1008: 
 1009: 		if (EG(exception) && fci->retval_ptr_ptr) {
 1010: 			zval_ptr_dtor(fci->retval_ptr_ptr);
 1011: 			*fci->retval_ptr_ptr = NULL;
 1012: 		}
 1013: 	}
 1014: 	zend_vm_stack_clear_multiple(TSRMLS_C);
 1015: 
 1016: 	if (EG(This)) {
 1017: 		zval_ptr_dtor(&EG(This));
 1018: 	}
 1019: 	EG(called_scope) = current_called_scope;
 1020: 	EG(scope) = current_scope;
 1021: 	EG(This) = current_this;
 1022: 	EG(current_execute_data) = EX(prev_execute_data);
 1023: 
 1024: 	if (EG(exception)) {
 1025: 		zend_throw_exception_internal(NULL TSRMLS_CC);
 1026: 	}
 1027: 	return SUCCESS;
 1028: }
 1029: /* }}} */
 1030: 
 1031: ZEND_API int zend_lookup_class_ex(const char *name, int name_length, const zend_literal *key, int use_autoload, zend_class_entry ***ce TSRMLS_DC) /* {{{ */
 1032: {
 1033: 	zval **args[1];
 1034: 	zval autoload_function;
 1035: 	zval *class_name_ptr;
 1036: 	zval *retval_ptr = NULL;
 1037: 	int retval, lc_length;
 1038: 	char *lc_name;
 1039: 	char *lc_free;
 1040: 	zend_fcall_info fcall_info;
 1041: 	zend_fcall_info_cache fcall_cache;
 1042: 	char dummy = 1;
 1043: 	ulong hash;
 1044: 	ALLOCA_FLAG(use_heap)
 1045: 
 1046: 	if (key) {
 1047: 		lc_name = Z_STRVAL(key->constant);
 1048: 		lc_length = Z_STRLEN(key->constant) + 1;
 1049: 		hash = key->hash_value;
 1050: 	} else {
 1051: 		if (name == NULL || !name_length) {
 1052: 			return FAILURE;
 1053: 		}
 1054: 
 1055: 		lc_free = lc_name = do_alloca(name_length + 1, use_heap);
 1056: 		zend_str_tolower_copy(lc_name, name, name_length);
 1057: 		lc_length = name_length + 1;
 1058: 
 1059: 		if (lc_name[0] == '\\') {
 1060: 			lc_name += 1;
 1061: 			lc_length -= 1;
 1062: 		}
 1063: 
 1064: 		hash = zend_inline_hash_func(lc_name, lc_length);
 1065: 	}
 1066: 
 1067: 	if (zend_hash_quick_find(EG(class_table), lc_name, lc_length, hash, (void **) ce) == SUCCESS) {
 1068: 		if (!key) {
 1069: 			free_alloca(lc_free, use_heap);
 1070: 		}
 1071: 		return SUCCESS;
 1072: 	}
 1073: 
 1074: 	/* The compiler is not-reentrant. Make sure we __autoload() only during run-time
 1075: 	 * (doesn't impact functionality of __autoload()
 1076: 	*/
 1077: 	if (!use_autoload || zend_is_compiling(TSRMLS_C)) {
 1078: 		if (!key) {
 1079: 			free_alloca(lc_free, use_heap);
 1080: 		}
 1081: 		return FAILURE;
 1082: 	}
 1083: 
 1084: 	if (EG(in_autoload) == NULL) {
 1085: 		ALLOC_HASHTABLE(EG(in_autoload));
 1086: 		zend_hash_init(EG(in_autoload), 0, NULL, NULL, 0);
 1087: 	}
 1088: 
 1089: 	if (zend_hash_quick_add(EG(in_autoload), lc_name, lc_length, hash, (void**)&dummy, sizeof(char), NULL) == FAILURE) {
 1090: 		if (!key) {
 1091: 			free_alloca(lc_free, use_heap);
 1092: 		}
 1093: 		return FAILURE;
 1094: 	}
 1095: 
 1096: 	ZVAL_STRINGL(&autoload_function, ZEND_AUTOLOAD_FUNC_NAME, sizeof(ZEND_AUTOLOAD_FUNC_NAME) - 1, 0);
 1097: 
 1098: 	ALLOC_ZVAL(class_name_ptr);
 1099: 	INIT_PZVAL(class_name_ptr);
 1100: 	if (name[0] == '\\') {
 1101: 		ZVAL_STRINGL(class_name_ptr, name+1, name_length-1, 1);
 1102: 	} else {
 1103: 		ZVAL_STRINGL(class_name_ptr, name, name_length, 1);
 1104: 	}
 1105: 
 1106: 	args[0] = &class_name_ptr;
 1107: 
 1108: 	fcall_info.size = sizeof(fcall_info);
 1109: 	fcall_info.function_table = EG(function_table);
 1110: 	fcall_info.function_name = &autoload_function;
 1111: 	fcall_info.symbol_table = NULL;
 1112: 	fcall_info.retval_ptr_ptr = &retval_ptr;
 1113: 	fcall_info.param_count = 1;
 1114: 	fcall_info.params = args;
 1115: 	fcall_info.object_ptr = NULL;
 1116: 	fcall_info.no_separation = 1;
 1117: 
 1118: 	fcall_cache.initialized = EG(autoload_func) ? 1 : 0;
 1119: 	fcall_cache.function_handler = EG(autoload_func);
 1120: 	fcall_cache.calling_scope = NULL;
 1121: 	fcall_cache.called_scope = NULL;
 1122: 	fcall_cache.object_ptr = NULL;
 1123: 
 1124: 	zend_exception_save(TSRMLS_C);
 1125: 	retval = zend_call_function(&fcall_info, &fcall_cache TSRMLS_CC);
 1126: 	zend_exception_restore(TSRMLS_C);
 1127: 
 1128: 	EG(autoload_func) = fcall_cache.function_handler;
 1129: 
 1130: 	zval_ptr_dtor(&class_name_ptr);
 1131: 
 1132: 	zend_hash_quick_del(EG(in_autoload), lc_name, lc_length, hash);
 1133: 
 1134: 	if (retval_ptr) {
 1135: 		zval_ptr_dtor(&retval_ptr);
 1136: 	}
 1137: 
 1138: 	if (retval == SUCCESS) {
 1139: 		retval = zend_hash_quick_find(EG(class_table), lc_name, lc_length, hash, (void **) ce);
 1140: 	}
 1141: 	if (!key) {
 1142: 		free_alloca(lc_free, use_heap);
 1143: 	}
 1144: 	return retval;
 1145: }
 1146: /* }}} */
 1147: 
 1148: ZEND_API int zend_lookup_class(const char *name, int name_length, zend_class_entry ***ce TSRMLS_DC) /* {{{ */
 1149: {
 1150: 	return zend_lookup_class_ex(name, name_length, NULL, 1, ce TSRMLS_CC);
 1151: }
 1152: /* }}} */
 1153: 
 1154: ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *string_name TSRMLS_DC) /* {{{ */
 1155: {
 1156: 	zval pv;
 1157: 	zend_op_array *new_op_array;
 1158: 	zend_op_array *original_active_op_array = EG(active_op_array);
 1159: 	zend_uint original_compiler_options;
 1160: 	int retval;
 1161: 
 1162: 	if (retval_ptr) {
 1163: 		Z_STRLEN(pv) = str_len + sizeof("return ;") - 1;
 1164: 		Z_STRVAL(pv) = emalloc(Z_STRLEN(pv) + 1);
 1165: 		memcpy(Z_STRVAL(pv), "return ", sizeof("return ") - 1);
 1166: 		memcpy(Z_STRVAL(pv) + sizeof("return ") - 1, str, str_len);
 1167: 		Z_STRVAL(pv)[Z_STRLEN(pv) - 1] = ';';
 1168: 		Z_STRVAL(pv)[Z_STRLEN(pv)] = '\0';
 1169: 	} else {
 1170: 		Z_STRLEN(pv) = str_len;
 1171: 		Z_STRVAL(pv) = str;
 1172: 	}
 1173: 	Z_TYPE(pv) = IS_STRING;
 1174: 
 1175: 	/*printf("Evaluating '%s'\n", pv.value.str.val);*/
 1176: 
 1177: 	original_compiler_options = CG(compiler_options);
 1178: 	CG(compiler_options) = ZEND_COMPILE_DEFAULT_FOR_EVAL;
 1179: 	new_op_array = zend_compile_string(&pv, string_name TSRMLS_CC);
 1180: 	CG(compiler_options) = original_compiler_options;
 1181: 
 1182: 	if (new_op_array) {
 1183: 		zval *local_retval_ptr=NULL;
 1184: 		zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
 1185: 		zend_op **original_opline_ptr = EG(opline_ptr);
 1186: 		int orig_interactive = CG(interactive);
 1187: 
 1188: 		EG(return_value_ptr_ptr) = &local_retval_ptr;
 1189: 		EG(active_op_array) = new_op_array;
 1190: 		EG(no_extensions)=1;
 1191: 		if (!EG(active_symbol_table)) {
 1192: 			zend_rebuild_symbol_table(TSRMLS_C);
 1193: 		}
 1194: 		CG(interactive) = 0;
 1195: 
 1196: 		zend_try {
 1197: 			zend_execute(new_op_array TSRMLS_CC);
 1198: 		} zend_catch {
 1199: 			destroy_op_array(new_op_array TSRMLS_CC);
 1200: 			efree(new_op_array);
 1201: 			zend_bailout();
 1202: 		} zend_end_try();
 1203: 
 1204: 		CG(interactive) = orig_interactive;
 1205: 		if (local_retval_ptr) {
 1206: 			if (retval_ptr) {
 1207: 				COPY_PZVAL_TO_ZVAL(*retval_ptr, local_retval_ptr);
 1208: 			} else {
 1209: 				zval_ptr_dtor(&local_retval_ptr);
 1210: 			}
 1211: 		} else {
 1212: 			if (retval_ptr) {
 1213: 				INIT_ZVAL(*retval_ptr);
 1214: 			}
 1215: 		}
 1216: 
 1217: 		EG(no_extensions)=0;
 1218: 		EG(opline_ptr) = original_opline_ptr;
 1219: 		EG(active_op_array) = original_active_op_array;
 1220: 		destroy_op_array(new_op_array TSRMLS_CC);
 1221: 		efree(new_op_array);
 1222: 		EG(return_value_ptr_ptr) = original_return_value_ptr_ptr;
 1223: 		retval = SUCCESS;
 1224: 	} else {
 1225: 		retval = FAILURE;
 1226: 	}
 1227: 	if (retval_ptr) {
 1228: 		zval_dtor(&pv);
 1229: 	}
 1230: 	return retval;
 1231: }
 1232: /* }}} */
 1233: 
 1234: ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC) /* {{{ */
 1235: {
 1236: 	return zend_eval_stringl(str, strlen(str), retval_ptr, string_name TSRMLS_CC);
 1237: }
 1238: /* }}} */
 1239: 
 1240: ZEND_API int zend_eval_stringl_ex(char *str, int str_len, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC) /* {{{ */
 1241: {
 1242: 	int result;
 1243: 
 1244: 	result = zend_eval_stringl(str, str_len, retval_ptr, string_name TSRMLS_CC);
 1245: 	if (handle_exceptions && EG(exception)) {
 1246: 		zend_exception_error(EG(exception), E_ERROR TSRMLS_CC);
 1247: 		result = FAILURE;
 1248: 	}
 1249: 	return result;
 1250: }
 1251: /* }}} */
 1252: 
 1253: ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC) /* {{{ */
 1254: {
 1255: 	return zend_eval_stringl_ex(str, strlen(str), retval_ptr, string_name, handle_exceptions TSRMLS_CC);
 1256: }
 1257: /* }}} */
 1258: 
 1259: void execute_new_code(TSRMLS_D) /* {{{ */
 1260: {
 1261: 	zend_op *opline, *end;
 1262: 	zend_op *ret_opline;
 1263: 	int orig_interactive;
 1264: 
 1265: 	if (!(CG(active_op_array)->fn_flags & ZEND_ACC_INTERACTIVE)
 1266: 		|| CG(context).backpatch_count>0
 1267: 		|| CG(active_op_array)->function_name
 1268: 		|| CG(active_op_array)->type!=ZEND_USER_FUNCTION) {
 1269: 		return;
 1270: 	}
 1271: 
 1272: 	ret_opline = get_next_op(CG(active_op_array) TSRMLS_CC);
 1273: 	ret_opline->opcode = ZEND_RETURN;
 1274: 	ret_opline->op1_type = IS_CONST;
 1275: 	ret_opline->op1.constant = zend_add_literal(CG(active_op_array), &EG(uninitialized_zval) TSRMLS_CC);
 1276: 	SET_UNUSED(ret_opline->op2);
 1277: 
 1278: 	if (!EG(start_op)) {
 1279: 		EG(start_op) = CG(active_op_array)->opcodes;
 1280: 	}
 1281: 
 1282: 	opline=EG(start_op);
 1283: 	end=CG(active_op_array)->opcodes+CG(active_op_array)->last;
 1284: 
 1285: 	while (opline<end) {
 1286: 		if (opline->op1_type == IS_CONST) {
 1287: 			opline->op1.zv = &CG(active_op_array)->literals[opline->op1.constant].constant;
 1288: 		}
 1289: 		if (opline->op2_type == IS_CONST) {
 1290: 			opline->op2.zv = &CG(active_op_array)->literals[opline->op2.constant].constant;
 1291: 		}
 1292: 		switch (opline->opcode) {
 1293: 			case ZEND_GOTO:
 1294: 				if (Z_TYPE_P(opline->op2.zv) != IS_LONG) {
 1295: 					zend_resolve_goto_label(CG(active_op_array), opline, 1 TSRMLS_CC);
 1296: 				}
 1297: 				/* break omitted intentionally */
 1298: 			case ZEND_JMP:
 1299: 				opline->op1.jmp_addr = &CG(active_op_array)->opcodes[opline->op1.opline_num];
 1300: 				break;
 1301: 			case ZEND_JMPZ:
 1302: 			case ZEND_JMPNZ:
 1303: 			case ZEND_JMPZ_EX:
 1304: 			case ZEND_JMPNZ_EX:
 1305: 			case ZEND_JMP_SET:
 1306: 			case ZEND_JMP_SET_VAR:
 1307: 				opline->op2.jmp_addr = &CG(active_op_array)->opcodes[opline->op2.opline_num];
 1308: 				break;
 1309: 		}
 1310: 		ZEND_VM_SET_OPCODE_HANDLER(opline);
 1311: 		opline++;
 1312: 	}
 1313: 	
 1314: 	zend_release_labels(1 TSRMLS_CC);
 1315: 	
 1316: 	EG(return_value_ptr_ptr) = NULL;
 1317: 	EG(active_op_array) = CG(active_op_array);
 1318: 	orig_interactive = CG(interactive);
 1319: 	CG(interactive) = 0;
 1320: 	zend_execute(CG(active_op_array) TSRMLS_CC);
 1321: 	CG(interactive) = orig_interactive;
 1322: 
 1323: 	if (EG(exception)) {
 1324: 		zend_exception_error(EG(exception), E_ERROR TSRMLS_CC);
 1325: 	}
 1326: 
 1327: 	CG(active_op_array)->last -= 1;	/* get rid of that ZEND_RETURN */
 1328: 	EG(start_op) = CG(active_op_array)->opcodes+CG(active_op_array)->last;
 1329: }
 1330: /* }}} */
 1331: 
 1332: ZEND_API void zend_timeout(int dummy) /* {{{ */
 1333: {
 1334: 	TSRMLS_FETCH();
 1335: 
 1336: 	if (zend_on_timeout) {
 1337: #ifdef ZEND_SIGNALS
 1338: 		/* 
 1339: 		   We got here because we got a timeout signal, so we are in a signal handler
 1340: 		   at this point. However, we want to be able to timeout any user-supplied
 1341: 		   shutdown functions, so pretend we are not in a signal handler while we are
 1342: 		   calling these 
 1343: 		*/
 1344: 		SIGG(running) = 0;
 1345: #endif
 1346: 		zend_on_timeout(EG(timeout_seconds) TSRMLS_CC);
 1347: 	}
 1348: 
 1349: 	zend_error(E_ERROR, "Maximum execution time of %d second%s exceeded", EG(timeout_seconds), EG(timeout_seconds) == 1 ? "" : "s");
 1350: }
 1351: /* }}} */
 1352: 
 1353: #ifdef ZEND_WIN32
 1354: static LRESULT CALLBACK zend_timeout_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) /* {{{ */
 1355: {
 1356: 	switch (message) {
 1357: 		case WM_DESTROY:
 1358: 			PostQuitMessage(0);
 1359: 			break;
 1360: 		case WM_REGISTER_ZEND_TIMEOUT:
 1361: 			/* wParam is the thread id pointer, lParam is the timeout amount in seconds */
 1362: 			if (lParam == 0) {
 1363: 				KillTimer(timeout_window, wParam);
 1364: 			} else {
 1365: #ifdef ZTS
 1366: 				void ***tsrm_ls;
 1367: #endif
 1368: 				SetTimer(timeout_window, wParam, lParam*1000, NULL);
 1369: #ifdef ZTS
 1370: 				tsrm_ls = ts_resource_ex(0, &wParam);
 1371: 				if (!tsrm_ls) {
 1372: 					/* shouldn't normally happen */
 1373: 					break;
 1374: 				}
 1375: #endif
 1376: 				EG(timed_out) = 0;
 1377: 			}
 1378: 			break;
 1379: 		case WM_UNREGISTER_ZEND_TIMEOUT:
 1380: 			/* wParam is the thread id pointer */
 1381: 			KillTimer(timeout_window, wParam);
 1382: 			break;
 1383: 		case WM_TIMER: {
 1384: #ifdef ZTS
 1385: 				void ***tsrm_ls;
 1386: 
 1387: 				tsrm_ls = ts_resource_ex(0, &wParam);
 1388: 				if (!tsrm_ls) {
 1389: 					/* Thread died before receiving its timeout? */
 1390: 					break;
 1391: 				}
 1392: #endif
 1393: 				KillTimer(timeout_window, wParam);
 1394: 				EG(timed_out) = 1;
 1395: 			}
 1396: 			break;
 1397: 		default:
 1398: 			return DefWindowProc(hWnd, message, wParam, lParam);
 1399: 	}
 1400: 	return 0;
 1401: }
 1402: /* }}} */
 1403: 
 1404: static unsigned __stdcall timeout_thread_proc(void *pArgs) /* {{{ */
 1405: {
 1406: 	MSG message;
 1407: 
 1408: 	wc.style=0;
 1409: 	wc.lpfnWndProc = zend_timeout_WndProc;
 1410: 	wc.cbClsExtra=0;
 1411: 	wc.cbWndExtra=0;
 1412: 	wc.hInstance=NULL;
 1413: 	wc.hIcon=NULL;
 1414: 	wc.hCursor=NULL;
 1415: 	wc.hbrBackground=(HBRUSH)(COLOR_BACKGROUND + 5);
 1416: 	wc.lpszMenuName=NULL;
 1417: 	wc.lpszClassName = "Zend Timeout Window";
 1418: 	if (!RegisterClass(&wc)) {
 1419: 		return -1;
 1420: 	}
 1421: 	timeout_window = CreateWindow(wc.lpszClassName, wc.lpszClassName, 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL);
 1422: 	SetEvent(timeout_thread_event);
 1423: 	while (GetMessage(&message, NULL, 0, 0)) {
 1424: 		SendMessage(timeout_window, message.message, message.wParam, message.lParam);
 1425: 		if (message.message == WM_QUIT) {
 1426: 			break;
 1427: 		}
 1428: 	}
 1429: 	DestroyWindow(timeout_window);
 1430: 	UnregisterClass(wc.lpszClassName, NULL);
 1431: 	SetEvent(timeout_thread_handle);
 1432: 	return 0;
 1433: }
 1434: /* }}} */
 1435: 
 1436: void zend_init_timeout_thread(void) /* {{{ */
 1437: {
 1438: 	timeout_thread_event = CreateEvent(NULL, FALSE, FALSE, NULL);
 1439: 	timeout_thread_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
 1440: 	_beginthreadex(NULL, 0, timeout_thread_proc, NULL, 0, &timeout_thread_id);
 1441: 	WaitForSingleObject(timeout_thread_event, INFINITE);
 1442: }
 1443: /* }}} */
 1444: 
 1445: void zend_shutdown_timeout_thread(void) /* {{{ */
 1446: {
 1447: 	if (!timeout_thread_initialized) {
 1448: 		return;
 1449: 	}
 1450: 	PostThreadMessage(timeout_thread_id, WM_QUIT, 0, 0);
 1451: 
 1452: 	/* Wait for thread termination */
 1453: 	WaitForSingleObject(timeout_thread_handle, 5000);
 1454: 	CloseHandle(timeout_thread_handle);
 1455: 	timeout_thread_initialized = 0;
 1456: }
 1457: /* }}} */
 1458: 
 1459: #endif
 1460: 
 1461: /* This one doesn't exists on QNX */
 1462: #ifndef SIGPROF
 1463: #define SIGPROF 27
 1464: #endif
 1465: 
 1466: void zend_set_timeout(long seconds, int reset_signals) /* {{{ */
 1467: {
 1468: 	TSRMLS_FETCH();
 1469: 
 1470: 	EG(timeout_seconds) = seconds;
 1471: 
 1472: #ifdef ZEND_WIN32
 1473: 	if(!seconds) {
 1474: 		return;
 1475: 	}
 1476: 	if (timeout_thread_initialized == 0 && InterlockedIncrement(&timeout_thread_initialized) == 1) {
 1477: 		/* We start up this process-wide thread here and not in zend_startup(), because if Zend
 1478: 		 * is initialized inside a DllMain(), you're not supposed to start threads from it.
 1479: 		 */
 1480: 		zend_init_timeout_thread();
 1481: 	}
 1482: 	PostThreadMessage(timeout_thread_id, WM_REGISTER_ZEND_TIMEOUT, (WPARAM) GetCurrentThreadId(), (LPARAM) seconds);
 1483: #else
 1484: #	ifdef HAVE_SETITIMER
 1485: 	{
 1486: 		struct itimerval t_r;		/* timeout requested */
 1487: 		int signo;
 1488: 
 1489: 		if(seconds) {
 1490: 			t_r.it_value.tv_sec = seconds;
 1491: 			t_r.it_value.tv_usec = t_r.it_interval.tv_sec = t_r.it_interval.tv_usec = 0;
 1492: 
 1493: #	ifdef __CYGWIN__
 1494: 			setitimer(ITIMER_REAL, &t_r, NULL);
 1495: 		}
 1496: 		signo = SIGALRM;
 1497: #	else
 1498: 			setitimer(ITIMER_PROF, &t_r, NULL);
 1499: 		}
 1500: 		signo = SIGPROF;
 1501: #	endif
 1502: 
 1503: 		if (reset_signals) {
 1504: #	ifdef ZEND_SIGNALS
 1505: 			zend_signal(signo, zend_timeout TSRMLS_CC);
 1506: #	else
 1507: 			sigset_t sigset;
 1508: 
 1509: 			signal(signo, zend_timeout);
 1510: 			sigemptyset(&sigset);
 1511: 			sigaddset(&sigset, signo);
 1512: 			sigprocmask(SIG_UNBLOCK, &sigset, NULL);
 1513: #	endif
 1514: 		}
 1515: 	}
 1516: #	endif /* HAVE_SETITIMER */
 1517: #endif
 1518: }
 1519: /* }}} */
 1520: 
 1521: void zend_unset_timeout(TSRMLS_D) /* {{{ */
 1522: {
 1523: #ifdef ZEND_WIN32
 1524: 	if(timeout_thread_initialized) {
 1525: 		PostThreadMessage(timeout_thread_id, WM_UNREGISTER_ZEND_TIMEOUT, (WPARAM) GetCurrentThreadId(), (LPARAM) 0);
 1526: 	}
 1527: #else
 1528: #	ifdef HAVE_SETITIMER
 1529: 	if (EG(timeout_seconds)) {
 1530: 		struct itimerval no_timeout;
 1531: 
 1532: 		no_timeout.it_value.tv_sec = no_timeout.it_value.tv_usec = no_timeout.it_interval.tv_sec = no_timeout.it_interval.tv_usec = 0;
 1533: 
 1534: #ifdef __CYGWIN__
 1535: 		setitimer(ITIMER_REAL, &no_timeout, NULL);
 1536: #else
 1537: 		setitimer(ITIMER_PROF, &no_timeout, NULL);
 1538: #endif
 1539: 	}
 1540: #	endif
 1541: #endif
 1542: }
 1543: /* }}} */
 1544: 
 1545: zend_class_entry *zend_fetch_class(const char *class_name, uint class_name_len, int fetch_type TSRMLS_DC) /* {{{ */
 1546: {
 1547: 	zend_class_entry **pce;
 1548: 	int use_autoload = (fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD) == 0;
 1549: 	int silent       = (fetch_type & ZEND_FETCH_CLASS_SILENT) != 0;
 1550: 
 1551: 	fetch_type &= ZEND_FETCH_CLASS_MASK;
 1552: 
 1553: check_fetch_type:
 1554: 	switch (fetch_type) {
 1555: 		case ZEND_FETCH_CLASS_SELF:
 1556: 			if (!EG(scope)) {
 1557: 				zend_error(E_ERROR, "Cannot access self:: when no class scope is active");
 1558: 			}
 1559: 			return EG(scope);
 1560: 		case ZEND_FETCH_CLASS_PARENT:
 1561: 			if (!EG(scope)) {
 1562: 				zend_error(E_ERROR, "Cannot access parent:: when no class scope is active");
 1563: 			}
 1564: 			if (!EG(scope)->parent) {
 1565: 				zend_error(E_ERROR, "Cannot access parent:: when current class scope has no parent");
 1566: 			}
 1567: 			return EG(scope)->parent;
 1568: 		case ZEND_FETCH_CLASS_STATIC:
 1569: 			if (!EG(called_scope)) {
 1570: 				zend_error(E_ERROR, "Cannot access static:: when no class scope is active");
 1571: 			}
 1572: 			return EG(called_scope);
 1573: 		case ZEND_FETCH_CLASS_AUTO: {
 1574: 				fetch_type = zend_get_class_fetch_type(class_name, class_name_len);
 1575: 				if (fetch_type!=ZEND_FETCH_CLASS_DEFAULT) {
 1576: 					goto check_fetch_type;
 1577: 				}
 1578: 			}
 1579: 			break;
 1580: 	}
 1581: 
 1582: 	if (zend_lookup_class_ex(class_name, class_name_len, NULL, use_autoload, &pce TSRMLS_CC) == FAILURE) {
 1583: 		if (use_autoload) {
 1584: 			if (!silent && !EG(exception)) {
 1585: 				if (fetch_type == ZEND_FETCH_CLASS_INTERFACE) {
 1586: 					zend_error(E_ERROR, "Interface '%s' not found", class_name);
 1587: 				} else if (fetch_type == ZEND_FETCH_CLASS_TRAIT) {
 1588:                 	zend_error(E_ERROR, "Trait '%s' not found", class_name);
 1589:                 } else {
 1590: 					zend_error(E_ERROR, "Class '%s' not found", class_name);
 1591: 				}	
 1592: 			}
 1593: 		}
 1594: 		return NULL;
 1595: 	}
 1596: 	return *pce;
 1597: }
 1598: /* }}} */
 1599: 
 1600: zend_class_entry *zend_fetch_class_by_name(const char *class_name, uint class_name_len, const zend_literal *key, int fetch_type TSRMLS_DC) /* {{{ */
 1601: {
 1602: 	zend_class_entry **pce;
 1603: 	int use_autoload = (fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD) == 0;
 1604: 
 1605: 	if (zend_lookup_class_ex(class_name, class_name_len, key, use_autoload, &pce TSRMLS_CC) == FAILURE) {
 1606: 		if (use_autoload) {
 1607: 			if ((fetch_type & ZEND_FETCH_CLASS_SILENT) == 0 && !EG(exception)) {
 1608: 				if ((fetch_type & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_INTERFACE) {
 1609: 					zend_error(E_ERROR, "Interface '%s' not found", class_name);
 1610: 				} else if ((fetch_type & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_TRAIT) {
 1611: 					zend_error(E_ERROR, "Trait '%s' not found", class_name);
 1612: 				} else {
 1613: 					zend_error(E_ERROR, "Class '%s' not found", class_name);
 1614: 				}	
 1615: 			}
 1616: 		}
 1617: 		return NULL;
 1618: 	}
 1619: 	return *pce;
 1620: }
 1621: /* }}} */
 1622: 
 1623: #define MAX_ABSTRACT_INFO_CNT 3
 1624: #define MAX_ABSTRACT_INFO_FMT "%s%s%s%s"
 1625: #define DISPLAY_ABSTRACT_FN(idx) \
 1626: 	ai.afn[idx] ? ZEND_FN_SCOPE_NAME(ai.afn[idx]) : "", \
 1627: 	ai.afn[idx] ? "::" : "", \
 1628: 	ai.afn[idx] ? ai.afn[idx]->common.function_name : "", \
 1629: 	ai.afn[idx] && ai.afn[idx + 1] ? ", " : (ai.afn[idx] && ai.cnt > MAX_ABSTRACT_INFO_CNT ? ", ..." : "")
 1630: 
 1631: typedef struct _zend_abstract_info {
 1632: 	zend_function *afn[MAX_ABSTRACT_INFO_CNT + 1];
 1633: 	int cnt;
 1634: 	int ctor;
 1635: } zend_abstract_info;
 1636: 
 1637: static int zend_verify_abstract_class_function(zend_function *fn, zend_abstract_info *ai TSRMLS_DC) /* {{{ */
 1638: {
 1639: 	if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) {
 1640: 		if (ai->cnt < MAX_ABSTRACT_INFO_CNT) {
 1641: 			ai->afn[ai->cnt] = fn;
 1642: 		}
 1643: 		if (fn->common.fn_flags & ZEND_ACC_CTOR) {
 1644: 			if (!ai->ctor) {
 1645: 				ai->cnt++;
 1646: 				ai->ctor = 1;
 1647: 			} else {
 1648: 				ai->afn[ai->cnt] = NULL;
 1649: 			}
 1650: 		} else {
 1651: 			ai->cnt++;
 1652: 		}
 1653: 	}
 1654: 	return 0;
 1655: }
 1656: /* }}} */
 1657: 
 1658: void zend_verify_abstract_class(zend_class_entry *ce TSRMLS_DC) /* {{{ */
 1659: {
 1660: 	zend_abstract_info ai;
 1661: 
 1662: 	if ((ce->ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) && !(ce->ce_flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
 1663: 		memset(&ai, 0, sizeof(ai));
 1664: 
 1665: 		zend_hash_apply_with_argument(&ce->function_table, (apply_func_arg_t) zend_verify_abstract_class_function, &ai TSRMLS_CC);
 1666: 
 1667: 		if (ai.cnt) {
 1668: 			zend_error(E_ERROR, "Class %s contains %d abstract method%s and must therefore be declared abstract or implement the remaining methods (" MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT ")",
 1669: 				ce->name, ai.cnt,
 1670: 				ai.cnt > 1 ? "s" : "",
 1671: 				DISPLAY_ABSTRACT_FN(0),
 1672: 				DISPLAY_ABSTRACT_FN(1),
 1673: 				DISPLAY_ABSTRACT_FN(2)
 1674: 				);
 1675: 		}
 1676: 	}
 1677: }
 1678: /* }}} */
 1679: 
 1680: ZEND_API void zend_reset_all_cv(HashTable *symbol_table TSRMLS_DC) /* {{{ */
 1681: {
 1682: 	zend_execute_data *ex;
 1683: 	int i;
 1684: 
 1685: 	for (ex = EG(current_execute_data); ex; ex = ex->prev_execute_data) {
 1686: 		if (ex->op_array && ex->symbol_table == symbol_table) {
 1687: 			for (i = 0; i < ex->op_array->last_var; i++) {
 1688: 				ex->CVs[i] = NULL;
 1689: 			}
 1690: 		}
 1691: 	}
 1692: }
 1693: /* }}} */
 1694: 
 1695: ZEND_API void zend_delete_variable(zend_execute_data *ex, HashTable *ht, const char *name, int name_len, ulong hash_value TSRMLS_DC) /* {{{ */
 1696: {
 1697: 	if (zend_hash_quick_del(ht, name, name_len, hash_value) == SUCCESS) {
 1698: 		name_len--;
 1699: 		while (ex && ex->symbol_table == ht) {
 1700: 			int i;
 1701: 
 1702: 			if (ex->op_array) {
 1703: 				for (i = 0; i < ex->op_array->last_var; i++) {
 1704: 					if (ex->op_array->vars[i].hash_value == hash_value &&
 1705: 						ex->op_array->vars[i].name_len == name_len &&
 1706: 						!memcmp(ex->op_array->vars[i].name, name, name_len)) {
 1707: 						ex->CVs[i] = NULL;
 1708: 						break;
 1709: 					}
 1710: 				}
 1711: 			}
 1712: 			ex = ex->prev_execute_data;
 1713: 		}
 1714: 	}
 1715: }
 1716: /* }}} */
 1717: 
 1718: ZEND_API int zend_delete_global_variable_ex(const char *name, int name_len, ulong hash_value TSRMLS_DC) /* {{{ */
 1719: {
 1720: 	zend_execute_data *ex;
 1721: 
 1722: 	if (zend_hash_quick_exists(&EG(symbol_table), name, name_len + 1, hash_value)) {
 1723: 		for (ex = EG(current_execute_data); ex; ex = ex->prev_execute_data) {
 1724: 			if (ex->op_array && ex->symbol_table == &EG(symbol_table)) {
 1725: 				int i;
 1726: 				for (i = 0; i < ex->op_array->last_var; i++) {
 1727: 					if (ex->op_array->vars[i].hash_value == hash_value &&
 1728: 						ex->op_array->vars[i].name_len == name_len &&
 1729: 						!memcmp(ex->op_array->vars[i].name, name, name_len)
 1730: 					) {
 1731: 						ex->CVs[i] = NULL;
 1732: 						break;
 1733: 					}
 1734: 				}
 1735: 			}
 1736: 		}
 1737: 		return zend_hash_quick_del(&EG(symbol_table), name, name_len + 1, hash_value);
 1738: 	}
 1739: 	return FAILURE;
 1740: }
 1741: /* }}} */
 1742: 
 1743: ZEND_API int zend_delete_global_variable(const char *name, int name_len TSRMLS_DC) /* {{{ */
 1744: {
 1745: 	return zend_delete_global_variable_ex(name, name_len, zend_inline_hash_func(name, name_len + 1) TSRMLS_CC);
 1746: }
 1747: /* }}} */
 1748: 
 1749: ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */
 1750: {
 1751: 	zend_uint i;
 1752: 	zend_execute_data *ex;
 1753: 
 1754: 	if (!EG(active_symbol_table)) {
 1755: 		
 1756: 		/* Search for last called user function */
 1757: 		ex = EG(current_execute_data);
 1758: 		while (ex && !ex->op_array) {
 1759: 			ex = ex->prev_execute_data;
 1760: 		}
 1761: 		if (ex && ex->symbol_table) {
 1762: 			EG(active_symbol_table) = ex->symbol_table;
 1763: 			return;
 1764: 		}
 1765: 
 1766: 		if (ex && ex->op_array) {
 1767: 			if (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
 1768: 				/*printf("Cache hit!  Reusing %x\n", symtable_cache[symtable_cache_ptr]);*/
 1769: 				EG(active_symbol_table) = *(EG(symtable_cache_ptr)--);
 1770: 			} else {
 1771: 				ALLOC_HASHTABLE(EG(active_symbol_table));
 1772: 				zend_hash_init(EG(active_symbol_table), ex->op_array->last_var, NULL, ZVAL_PTR_DTOR, 0);
 1773: 				/*printf("Cache miss!  Initialized %x\n", EG(active_symbol_table));*/
 1774: 			}
 1775: 			ex->symbol_table = EG(active_symbol_table);
 1776: 
 1777: 			if (ex->op_array->this_var != -1 &&
 1778: 			    !ex->CVs[ex->op_array->this_var] &&
 1779: 			    EG(This)) {
 1780: 				ex->CVs[ex->op_array->this_var] = (zval**)ex->CVs + ex->op_array->last_var + ex->op_array->this_var;
 1781: 				*ex->CVs[ex->op_array->this_var] = EG(This);
 1782:  			}
 1783: 			for (i = 0; i < ex->op_array->last_var; i++) {
 1784: 				if (ex->CVs[i]) {
 1785: 					zend_hash_quick_update(EG(active_symbol_table),
 1786: 						ex->op_array->vars[i].name,
 1787: 						ex->op_array->vars[i].name_len + 1,
 1788: 						ex->op_array->vars[i].hash_value,
 1789: 						(void**)ex->CVs[i],
 1790: 						sizeof(zval*),
 1791: 						(void**)&ex->CVs[i]);
 1792: 				}
 1793: 			}
 1794: 		}
 1795: 	}
 1796: }
 1797: /* }}} */
 1798: 
 1799: /*
 1800:  * Local variables:
 1801:  * tab-width: 4
 1802:  * c-basic-offset: 4
 1803:  * indent-tabs-mode: t
 1804:  * End:
 1805:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>