root/Zend/zend_execute_API.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. zend_handle_sigsegv
  2. zend_extension_activator
  3. zend_extension_deactivator
  4. clean_non_persistent_function
  5. clean_non_persistent_function_full
  6. clean_non_persistent_class
  7. clean_non_persistent_class_full
  8. init_executor
  9. zval_call_destructor
  10. shutdown_destructors
  11. shutdown_executor
  12. get_active_class_name
  13. get_active_function_name
  14. zend_get_executed_filename
  15. zend_get_executed_lineno
  16. zend_is_executing
  17. _zval_ptr_dtor
  18. _zval_internal_ptr_dtor
  19. zend_is_true
  20. zval_update_constant_ex
  21. zval_update_constant_inline_change
  22. zval_update_constant_no_inline_change
  23. zval_update_constant
  24. call_user_function
  25. call_user_function_ex
  26. zend_call_function
  27. zend_lookup_class_ex
  28. zend_lookup_class
  29. zend_eval_stringl
  30. zend_eval_string
  31. zend_eval_stringl_ex
  32. zend_eval_string_ex
  33. execute_new_code
  34. zend_timeout
  35. tq_timer_cb
  36. zend_set_timeout
  37. zend_unset_timeout
  38. zend_fetch_class
  39. zend_fetch_class_by_name
  40. zend_verify_abstract_class_function
  41. zend_verify_abstract_class
  42. zend_reset_all_cv
  43. zend_delete_variable
  44. zend_delete_global_variable_ex
  45. zend_delete_global_variable
  46. zend_rebuild_symbol_table

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

/* [<][>][^][v][top][bottom][index][help] */