1999-04-07 18:10:10 +00:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Zend Engine |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2008-12-31 11:12:40 +00:00
| Copyright ( c ) 1998 - 2009 Zend Technologies Ltd . ( http : //www.zend.com) |
1999-04-07 18:10:10 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2001-12-11 15:16:21 +00:00
| This source file is subject to version 2.00 of the Zend license , |
2003-08-07 07:37:19 +00:00
| that is bundled with this package in the file LICENSE , and is |
2003-06-10 20:04:29 +00:00
| available through the world - wide - web at the following url : |
2001-12-11 15:16:21 +00:00
| http : //www.zend.com/license/2_00.txt. |
1999-07-16 14:58:16 +00:00
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world - wide - web , please send a note to |
| license @ zend . com so we can mail you a copy immediately . |
1999-04-07 18:10:10 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Authors : Andi Gutmans < andi @ zend . com > |
| Zeev Suraski < zeev @ zend . com > |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
2003-02-01 01:49:15 +00:00
/* $Id$ */
1999-07-16 14:58:16 +00:00
1999-04-07 18:10:10 +00:00
# include <stdio.h>
# include <signal.h>
# include "zend.h"
# include "zend_compile.h"
# include "zend_execute.h"
# include "zend_API.h"
# include "zend_ptr_stack.h"
# include "zend_constants.h"
# include "zend_extensions.h"
2008-07-08 07:05:04 +00:00
# include "zend_closures.h"
2004-02-12 10:38:14 +00:00
# include "zend_exceptions.h"
2004-09-23 21:43:32 +00:00
# include "zend_vm.h"
2009-03-18 10:49:36 +00:00
# include "zend_float.h"
2001-05-30 08:23:15 +00:00
# ifdef HAVE_SYS_TIME_H
2000-06-16 02:49:21 +00:00
# include <sys/time.h>
# endif
1999-04-07 18:10:10 +00:00
2001-07-27 10:10:39 +00:00
ZEND_API void ( * zend_execute ) ( zend_op_array * op_array TSRMLS_DC ) ;
2003-01-11 16:12:44 +00:00
ZEND_API void ( * zend_execute_internal ) ( zend_execute_data * execute_data_ptr , int return_value_used TSRMLS_DC ) ;
1999-04-07 18:10:10 +00:00
2003-08-06 07:38:56 +00:00
/* true globals */
2008-08-12 21:52:54 +00:00
ZEND_API const zend_fcall_info empty_fcall_info = { 0 , NULL , NULL , NULL , NULL , 0 , NULL , NULL , 0 } ;
ZEND_API const zend_fcall_info_cache empty_fcall_info_cache = { 0 , NULL , NULL , NULL , NULL } ;
2003-08-05 10:24:40 +00:00
2003-08-05 23:50:59 +00:00
# ifdef ZEND_WIN32
# include <process.h>
2000-06-16 01:54:56 +00:00
static WNDCLASS wc ;
2000-06-16 14:27:28 +00:00
static HWND timeout_window ;
static HANDLE timeout_thread_event ;
2005-12-09 18:09:08 +00:00
static HANDLE timeout_thread_handle ;
2000-06-16 14:27:28 +00:00
static DWORD timeout_thread_id ;
static int timeout_thread_initialized = 0 ;
2000-06-16 01:54:56 +00:00
# endif
2006-03-03 23:20:29 +00:00
UChar u_main [ sizeof ( " main " ) ] ;
UChar u_return [ sizeof ( " return " ) ] ;
2009-03-19 18:32:45 +00:00
UChar u_doublecolon [ sizeof ( " :: " ) ] ;
2005-08-11 23:35:03 +00:00
2007-07-21 00:34:41 +00:00
void init_unicode_strings ( void )
{
2005-08-11 23:35:03 +00:00
u_charsToUChars ( " main " , u_main , sizeof ( " main " ) ) ;
u_charsToUChars ( " return " , u_return , sizeof ( " return " ) ) ;
2006-03-03 23:20:29 +00:00
u_charsToUChars ( " :: " , u_doublecolon , sizeof ( " :: " ) ) ;
2005-08-11 23:35:03 +00:00
}
2006-03-17 08:47:54 +00:00
#if 0 &&ZEND_DEBUG
1999-04-07 18:10:10 +00:00
static void ( * original_sigsegv_handler ) ( int ) ;
2007-07-11 11:19:58 +00:00
static void zend_handle_sigsegv ( int dummy ) /* { { { */
1999-04-07 18:10:10 +00:00
{
fflush ( stdout ) ;
1999-05-22 11:20:56 +00:00
fflush ( stderr ) ;
2007-11-02 00:15:13 +00:00
if ( original_sigsegv_handler = = zend_handle_sigsegv ) {
1999-07-09 07:35:13 +00:00
signal ( SIGSEGV , original_sigsegv_handler ) ;
} else {
signal ( SIGSEGV , SIG_DFL ) ;
}
1999-05-22 16:10:51 +00:00
{
2001-07-27 10:10:39 +00:00
TSRMLS_FETCH ( ) ;
1999-05-22 16:10:51 +00:00
2006-02-18 19:33:26 +00:00
fprintf ( stderr , " SIGSEGV caught on opcode %d on opline %d of %s() at %s:%d \n \n " ,
1999-05-22 16:10:51 +00:00
active_opline - > opcode ,
active_opline - EG ( active_op_array ) - > opcodes ,
2006-02-21 20:12:43 +00:00
get_active_function_name ( TSRMLS_C ) . s ,
2001-07-27 10:10:39 +00:00
zend_get_executed_filename ( TSRMLS_C ) ,
zend_get_executed_lineno ( TSRMLS_C ) ) ;
1999-05-22 16:10:51 +00:00
}
1999-07-09 07:35:13 +00:00
if ( original_sigsegv_handler ! = zend_handle_sigsegv ) {
original_sigsegv_handler ( dummy ) ;
}
1999-04-07 18:10:10 +00:00
}
2007-07-11 11:19:58 +00:00
/* }}} */
1999-07-09 07:35:13 +00:00
# endif
1999-04-07 18:10:10 +00:00
2007-07-11 11:19:58 +00:00
static void zend_extension_activator ( zend_extension * extension TSRMLS_DC ) /* { { { */
1999-04-07 18:10:10 +00:00
{
if ( extension - > activate ) {
extension - > activate ( ) ;
}
}
2007-07-11 11:19:58 +00:00
/* }}} */
1999-04-07 18:10:10 +00:00
2007-07-11 11:19:58 +00:00
static void zend_extension_deactivator ( zend_extension * extension TSRMLS_DC ) /* { { { */
1999-04-07 18:10:10 +00:00
{
if ( extension - > deactivate ) {
extension - > deactivate ( ) ;
}
}
2007-07-11 11:19:58 +00:00
/* }}} */
1999-04-07 18:10:10 +00:00
2007-07-11 11:19:58 +00:00
static int clean_non_persistent_function ( zend_function * function TSRMLS_DC ) /* { { { */
2000-06-04 22:09:16 +00:00
{
2006-03-13 11:13:55 +00:00
return ( function - > type = = ZEND_INTERNAL_FUNCTION ) ? ZEND_HASH_APPLY_STOP : ZEND_HASH_APPLY_REMOVE ;
2000-06-04 22:09:16 +00:00
}
2007-07-11 11:19:58 +00:00
/* }}} */
2000-06-04 22:09:16 +00:00
2007-07-11 11:19:58 +00:00
static int clean_non_persistent_function_full ( zend_function * function TSRMLS_DC ) /* { { { */
2000-06-04 22:09:16 +00:00
{
2006-03-14 11:24:30 +00:00
return ( function - > type ! = ZEND_INTERNAL_FUNCTION ) ;
2006-03-13 11:13:55 +00:00
}
2007-07-11 11:19:58 +00:00
/* }}} */
2006-03-13 11:13:55 +00:00
2007-07-11 11:19:58 +00:00
static int clean_non_persistent_class ( zend_class_entry * * ce TSRMLS_DC ) /* { { { */
2006-03-13 11:13:55 +00:00
{
return ( ( * ce ) - > type = = ZEND_INTERNAL_CLASS ) ? ZEND_HASH_APPLY_STOP : ZEND_HASH_APPLY_REMOVE ;
}
2007-07-11 11:19:58 +00:00
/* }}} */
2006-03-13 11:13:55 +00:00
2007-07-11 11:19:58 +00:00
static int clean_non_persistent_class_full ( zend_class_entry * * ce TSRMLS_DC ) /* { { { */
2006-03-13 11:13:55 +00:00
{
2006-03-14 11:24:30 +00:00
return ( ( * ce ) - > type ! = ZEND_INTERNAL_CLASS ) ;
2000-06-04 22:09:16 +00:00
}
2007-07-11 11:19:58 +00:00
/* }}} */
2000-06-04 22:09:16 +00:00
2007-07-11 11:19:58 +00:00
void init_executor ( TSRMLS_D ) /* { { { */
1999-04-07 18:10:10 +00:00
{
2009-03-18 10:49:36 +00:00
zend_init_fpu ( TSRMLS_C ) ;
1999-12-19 06:39:17 +00:00
INIT_ZVAL ( EG ( uninitialized_zval ) ) ;
2007-11-02 00:15:13 +00:00
/* trick to make uninitialized_zval never be modified, passed by ref, etc. */
2007-10-07 05:15:07 +00:00
Z_ADDREF ( EG ( uninitialized_zval ) ) ;
1999-12-19 06:39:17 +00:00
INIT_ZVAL ( EG ( error_zval ) ) ;
1999-04-07 18:10:10 +00:00
EG ( uninitialized_zval_ptr ) = & EG ( uninitialized_zval ) ;
EG ( error_zval_ptr ) = & EG ( error_zval ) ;
zend_ptr_stack_init ( & EG ( arg_types_stack ) ) ;
1999-07-15 12:17:34 +00:00
/* destroys stack frame, therefore makes core dumps worthless */
1999-12-19 18:54:40 +00:00
#if 0 &&ZEND_DEBUG
1999-04-07 18:10:10 +00:00
original_sigsegv_handler = signal ( SIGSEGV , zend_handle_sigsegv ) ;
1999-07-15 12:17:34 +00:00
# endif
2001-09-10 00:07:32 +00:00
EG ( return_value_ptr_ptr ) = NULL ;
1999-12-19 06:39:17 +00:00
2007-11-02 00:15:13 +00:00
EG ( symtable_cache_ptr ) = EG ( symtable_cache ) - 1 ;
EG ( symtable_cache_limit ) = EG ( symtable_cache ) + SYMTABLE_CACHE_SIZE - 1 ;
EG ( no_extensions ) = 0 ;
1999-04-07 18:10:10 +00:00
EG ( function_table ) = CG ( function_table ) ;
EG ( class_table ) = CG ( class_table ) ;
2000-02-04 14:45:58 +00:00
EG ( in_execution ) = 0 ;
2004-03-24 14:30:59 +00:00
EG ( in_autoload ) = NULL ;
2004-08-23 20:57:40 +00:00
EG ( autoload_func ) = NULL ;
2008-10-02 19:53:48 +00:00
EG ( error_handling ) = EH_NORMAL ;
2000-02-04 14:45:58 +00:00
2008-01-24 09:41:48 +00:00
zend_vm_stack_init ( TSRMLS_C ) ;
zend_vm_stack_push ( ( void * ) NULL TSRMLS_CC ) ;
1999-04-12 18:29:09 +00:00
2005-08-11 23:35:03 +00:00
zend_u_hash_init ( & EG ( symbol_table ) , 50 , NULL , ZVAL_PTR_DTOR , 0 , UG ( unicode ) ) ;
2002-01-20 20:42:15 +00:00
{
zval * globals ;
ALLOC_ZVAL ( globals ) ;
2007-10-07 05:15:07 +00:00
Z_SET_REFCOUNT_P ( globals , 1 ) ;
Z_SET_ISREF_P ( globals ) ;
2006-02-20 19:03:43 +00:00
Z_TYPE_P ( globals ) = IS_ARRAY ;
Z_ARRVAL_P ( globals ) = & EG ( symbol_table ) ;
2006-09-19 10:38:31 +00:00
zend_ascii_hash_update ( & EG ( symbol_table ) , " GLOBALS " , sizeof ( " GLOBALS " ) , & globals , sizeof ( zval * ) , NULL ) ;
2002-01-20 20:42:15 +00:00
}
1999-04-07 18:10:10 +00:00
EG ( active_symbol_table ) = & EG ( symbol_table ) ;
2003-08-07 07:37:19 +00:00
2001-07-31 04:53:54 +00:00
zend_llist_apply ( & zend_extensions , ( llist_apply_func_t ) zend_extension_activator TSRMLS_CC ) ;
1999-05-25 22:55:13 +00:00
EG ( opline_ptr ) = NULL ;
1999-11-30 20:15:04 +00:00
2000-03-10 16:36:30 +00:00
zend_hash_init ( & EG ( included_files ) , 5 , NULL , NULL , 0 ) ;
2000-01-24 19:00:30 +00:00
EG ( ticks_count ) = 0 ;
2000-04-19 15:08:06 +00:00
EG ( user_error_handler ) = NULL ;
2000-06-16 14:27:28 +00:00
2003-02-14 12:25:09 +00:00
EG ( current_execute_data ) = NULL ;
2004-01-10 11:43:42 +00:00
zend_stack_init ( & EG ( user_error_handlers_error_reporting ) ) ;
2000-06-17 18:04:58 +00:00
zend_ptr_stack_init ( & EG ( user_error_handlers ) ) ;
2002-08-16 00:41:37 +00:00
zend_ptr_stack_init ( & EG ( user_exception_handlers ) ) ;
2006-06-20 23:00:02 +00:00
zend_ptr_stack_init ( & UG ( conv_error_handlers ) ) ;
2000-06-17 18:04:58 +00:00
2002-05-31 12:09:19 +00:00
zend_objects_store_init ( & EG ( objects_store ) , 1024 ) ;
2001-10-26 14:13:42 +00:00
EG ( full_tables_cleanup ) = 0 ;
2000-06-16 14:27:28 +00:00
# ifdef ZEND_WIN32
EG ( timed_out ) = 0 ;
# endif
2001-08-30 15:26:30 +00:00
EG ( exception ) = NULL ;
2008-08-14 10:06:39 +00:00
EG ( prev_exception ) = NULL ;
2001-12-06 17:47:04 +00:00
2002-03-01 14:27:26 +00:00
EG ( scope ) = NULL ;
2007-09-26 07:16:33 +00:00
EG ( called_scope ) = NULL ;
2001-12-13 16:55:04 +00:00
2002-03-01 14:27:26 +00:00
EG ( This ) = NULL ;
2007-11-02 00:15:13 +00:00
2006-10-11 16:11:40 +00:00
EG ( active_op_array ) = NULL ;
2006-09-11 14:28:19 +00:00
EG ( active ) = 1 ;
1999-04-07 18:10:10 +00:00
}
2007-07-11 11:19:58 +00:00
/* }}} */
1999-04-07 18:10:10 +00:00
2007-07-11 11:19:58 +00:00
static int zval_call_destructor ( zval * * zv TSRMLS_DC ) /* { { { */
2006-07-12 07:54:18 +00:00
{
2007-10-07 05:15:07 +00:00
if ( Z_TYPE_PP ( zv ) = = IS_OBJECT & & Z_REFCOUNT_PP ( zv ) = = 1 ) {
2006-07-12 07:54:18 +00:00
return ZEND_HASH_APPLY_REMOVE ;
} else {
return ZEND_HASH_APPLY_KEEP ;
}
}
2007-07-11 11:19:58 +00:00
/* }}} */
2006-07-12 07:54:18 +00:00
2007-07-11 11:19:58 +00:00
void shutdown_destructors ( TSRMLS_D ) /* { { { */
{
2004-07-25 07:14:49 +00:00
zend_try {
2006-07-12 07:54:18 +00:00
int symbols ;
do {
symbols = zend_hash_num_elements ( & EG ( symbol_table ) ) ;
zend_hash_reverse_apply ( & EG ( symbol_table ) , ( apply_func_t ) zval_call_destructor TSRMLS_CC ) ;
} while ( symbols ! = zend_hash_num_elements ( & EG ( symbol_table ) ) ) ;
2004-07-25 07:14:49 +00:00
zend_objects_store_call_destructors ( & EG ( objects_store ) TSRMLS_CC ) ;
2004-09-17 10:13:52 +00:00
} zend_catch {
/* if we couldn't destruct cleanly, mark all objects as destructed anyway */
zend_objects_store_mark_destructed ( & EG ( objects_store ) TSRMLS_CC ) ;
2004-07-25 07:14:49 +00:00
} zend_end_try ( ) ;
}
2007-07-11 11:19:58 +00:00
/* }}} */
2004-07-25 07:14:49 +00:00
2007-07-11 11:19:58 +00:00
void shutdown_executor ( TSRMLS_D ) /* { { { */
1999-04-07 18:10:10 +00:00
{
2001-07-21 14:25:27 +00:00
zend_try {
2003-01-29 14:33:18 +00:00
/* Removed because this can not be safely done, e.g. in this situation:
Object 1 creates object 2
Object 3 holds reference to object 2.
Now when 1 and 2 are destroyed , 3 can still access 2 in its destructor , with
very problematic results */
/* zend_objects_store_call_destructors(&EG(objects_store) TSRMLS_CC); */
/* Moved after symbol table cleaners, because some of the cleaners can call
destructors , which would use EG ( symtable_cache_ptr ) and thus leave leaks */
/* while (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
2001-07-20 14:20:34 +00:00
zend_hash_destroy ( * EG ( symtable_cache_ptr ) ) ;
efree ( * EG ( symtable_cache_ptr ) ) ;
EG ( symtable_cache_ptr ) - - ;
}
2003-01-29 14:33:18 +00:00
*/
2001-07-31 04:53:54 +00:00
zend_llist_apply ( & zend_extensions , ( llist_apply_func_t ) zend_extension_deactivator TSRMLS_CC ) ;
2003-12-17 14:25:12 +00:00
zend_hash_graceful_reverse_destroy ( & EG ( symbol_table ) ) ;
2003-07-27 13:47:58 +00:00
} zend_end_try ( ) ;
2003-07-27 15:59:37 +00:00
zend_try {
zval * zeh ;
/* remove error handlers before destroying classes and functions,
2007-11-02 00:15:13 +00:00
* so that if handler used some class , crash would not happen */
2003-07-27 15:59:37 +00:00
if ( EG ( user_error_handler ) ) {
zeh = EG ( user_error_handler ) ;
EG ( user_error_handler ) = NULL ;
zval_dtor ( zeh ) ;
FREE_ZVAL ( zeh ) ;
}
if ( EG ( user_exception_handler ) ) {
zeh = EG ( user_exception_handler ) ;
EG ( user_exception_handler ) = NULL ;
zval_dtor ( zeh ) ;
FREE_ZVAL ( zeh ) ;
}
2006-06-20 23:00:02 +00:00
if ( UG ( conv_error_handler ) ) {
zeh = UG ( conv_error_handler ) ;
UG ( conv_error_handler ) = NULL ;
zval_dtor ( zeh ) ;
FREE_ZVAL ( zeh ) ;
}
2004-01-10 11:43:42 +00:00
zend_stack_destroy ( & EG ( user_error_handlers_error_reporting ) ) ;
zend_stack_init ( & EG ( user_error_handlers_error_reporting ) ) ;
2003-07-27 15:59:37 +00:00
zend_ptr_stack_clean ( & EG ( user_error_handlers ) , ZVAL_DESTRUCTOR , 1 ) ;
zend_ptr_stack_clean ( & EG ( user_exception_handlers ) , ZVAL_DESTRUCTOR , 1 ) ;
2006-06-20 23:00:02 +00:00
zend_ptr_stack_clean ( & UG ( conv_error_handlers ) , ZVAL_DESTRUCTOR , 1 ) ;
2003-07-27 15:59:37 +00:00
} zend_end_try ( ) ;
2003-08-07 07:37:19 +00:00
2003-07-27 13:47:58 +00:00
zend_try {
2003-01-29 17:54:48 +00:00
/* Cleanup static data for functions and arrays.
2007-11-02 00:15:13 +00:00
* We need a separate cleanup stage because of the following problem :
* Suppose we destroy class X , which destroys the class ' s function table ,
* and in the function table we have function foo ( ) that has static $ bar .
* Now if an object of class X is assigned to $ bar , its destructor will be
* called and will fail since X ' s function table is in mid - destruction .
* So we want first of all to clean up all data and then move to tables destruction .
* Note that only run - time accessed data need to be cleaned up , pre - defined data can
* not contain objects and thus are not probelmatic */
2006-03-13 11:13:55 +00:00
if ( EG ( full_tables_cleanup ) ) {
zend_hash_apply ( EG ( function_table ) , ( apply_func_t ) zend_cleanup_function_data_full TSRMLS_CC ) ;
} else {
zend_hash_reverse_apply ( EG ( function_table ) , ( apply_func_t ) zend_cleanup_function_data TSRMLS_CC ) ;
}
2003-01-30 00:44:56 +00:00
zend_hash_apply ( EG ( class_table ) , ( apply_func_t ) zend_cleanup_class_data TSRMLS_CC ) ;
2003-03-02 15:24:04 +00:00
2008-01-24 09:41:48 +00:00
zend_vm_stack_destroy ( TSRMLS_C ) ;
2003-03-02 15:24:04 +00:00
2008-08-11 17:33:02 +00:00
zend_objects_store_free_object_storage ( & EG ( objects_store ) TSRMLS_CC ) ;
2001-07-20 14:20:34 +00:00
/* Destroy all op arrays */
2001-10-26 14:13:42 +00:00
if ( EG ( full_tables_cleanup ) ) {
2006-03-13 11:13:55 +00:00
zend_hash_apply ( EG ( function_table ) , ( apply_func_t ) clean_non_persistent_function_full TSRMLS_CC ) ;
zend_hash_apply ( EG ( class_table ) , ( apply_func_t ) clean_non_persistent_class_full TSRMLS_CC ) ;
2001-10-23 01:23:36 +00:00
} else {
2006-03-13 11:13:55 +00:00
zend_hash_reverse_apply ( EG ( function_table ) , ( apply_func_t ) clean_non_persistent_function TSRMLS_CC ) ;
zend_hash_reverse_apply ( EG ( class_table ) , ( apply_func_t ) clean_non_persistent_class TSRMLS_CC ) ;
2001-10-23 01:23:36 +00:00
}
2003-01-29 14:33:18 +00:00
while ( EG ( symtable_cache_ptr ) > = EG ( symtable_cache ) ) {
zend_hash_destroy ( * EG ( symtable_cache_ptr ) ) ;
2003-10-14 14:36:23 +00:00
FREE_HASHTABLE ( * EG ( symtable_cache_ptr ) ) ;
2003-01-29 14:33:18 +00:00
EG ( symtable_cache_ptr ) - - ;
}
2001-07-21 14:25:27 +00:00
} zend_end_try ( ) ;
2000-06-04 22:09:16 +00:00
2002-09-16 01:36:48 +00:00
zend_try {
clean_non_persistent_constants ( TSRMLS_C ) ;
} zend_end_try ( ) ;
2001-07-21 14:25:27 +00:00
zend_try {
2006-03-17 08:47:54 +00:00
#if 0 &&ZEND_DEBUG
1999-07-09 07:35:13 +00:00
signal ( SIGSEGV , original_sigsegv_handler ) ;
# endif
2000-02-01 11:41:15 +00:00
2001-07-20 14:20:34 +00:00
zend_hash_destroy ( & EG ( included_files ) ) ;
2000-04-19 15:08:06 +00:00
2003-08-04 11:02:53 +00:00
zend_ptr_stack_destroy ( & EG ( arg_types_stack ) ) ;
2004-01-10 11:43:42 +00:00
zend_stack_destroy ( & EG ( user_error_handlers_error_reporting ) ) ;
2001-07-20 14:20:34 +00:00
zend_ptr_stack_destroy ( & EG ( user_error_handlers ) ) ;
2002-08-16 00:41:37 +00:00
zend_ptr_stack_destroy ( & EG ( user_exception_handlers ) ) ;
2006-06-20 23:00:02 +00:00
zend_ptr_stack_destroy ( & UG ( conv_error_handlers ) ) ;
2002-05-31 12:09:19 +00:00
zend_objects_store_destroy ( & EG ( objects_store ) ) ;
2004-03-24 14:30:59 +00:00
if ( EG ( in_autoload ) ) {
zend_hash_destroy ( EG ( in_autoload ) ) ;
2004-03-25 08:14:33 +00:00
FREE_HASHTABLE ( EG ( in_autoload ) ) ;
2004-03-24 14:30:59 +00:00
}
2001-07-21 14:25:27 +00:00
} zend_end_try ( ) ;
2009-03-18 10:49:36 +00:00
zend_shutdown_fpu ( TSRMLS_C ) ;
2006-09-11 14:28:19 +00:00
EG ( active ) = 0 ;
1999-04-07 18:10:10 +00:00
}
2007-07-11 11:19:58 +00:00
/* }}} */
1999-04-07 18:10:10 +00:00
2004-03-16 10:14:57 +00:00
/* return class name and "::" or "". */
2007-07-11 11:19:58 +00:00
ZEND_API zstr get_active_class_name ( char * * space TSRMLS_DC ) /* { { { */
2004-03-16 10:14:57 +00:00
{
if ( ! zend_is_executing ( TSRMLS_C ) ) {
if ( space ) {
* space = " " ;
}
2006-02-26 11:57:14 +00:00
return EMPTY_ZSTR ;
2004-03-16 10:14:57 +00:00
}
2007-11-20 09:51:44 +00:00
switch ( EG ( current_execute_data ) - > function_state . function - > type ) {
2004-03-16 10:14:57 +00:00
case ZEND_USER_FUNCTION :
case ZEND_INTERNAL_FUNCTION :
{
2007-11-20 09:51:44 +00:00
zend_class_entry * ce = EG ( current_execute_data ) - > function_state . function - > common . scope ;
2004-03-16 10:14:57 +00:00
if ( space ) {
* space = ce ? " :: " : " " ;
}
2006-02-26 11:57:14 +00:00
return ce ? ce - > name : EMPTY_ZSTR ;
2004-03-16 10:14:57 +00:00
}
default :
if ( space ) {
* space = " " ;
}
2006-02-26 11:57:14 +00:00
return EMPTY_ZSTR ;
2004-03-16 10:14:57 +00:00
}
}
2007-07-11 11:19:58 +00:00
/* }}} */
2004-03-16 10:14:57 +00:00
2007-07-11 11:19:58 +00:00
ZEND_API zstr get_active_function_name ( TSRMLS_D ) /* { { { */
1999-04-07 18:10:10 +00:00
{
2006-02-26 11:57:14 +00:00
zstr ret ;
2002-04-20 20:14:14 +00:00
if ( ! zend_is_executing ( TSRMLS_C ) ) {
2006-02-26 11:57:14 +00:00
return NULL_ZSTR ;
2002-04-20 20:14:14 +00:00
}
2007-11-20 09:51:44 +00:00
switch ( EG ( current_execute_data ) - > function_state . function - > type ) {
1999-04-07 18:10:10 +00:00
case ZEND_USER_FUNCTION : {
2007-11-20 09:51:44 +00:00
zstr function_name = ( ( zend_op_array * ) EG ( current_execute_data ) - > function_state . function ) - > function_name ;
2003-08-07 07:37:19 +00:00
2006-02-21 20:12:43 +00:00
if ( function_name . v ) {
1999-04-07 18:10:10 +00:00
return function_name ;
} else {
2009-03-26 20:02:53 +00:00
ret . u = u_main ;
1999-04-07 18:10:10 +00:00
}
2006-02-26 11:57:14 +00:00
return ret ;
1999-04-07 18:10:10 +00:00
}
break ;
case ZEND_INTERNAL_FUNCTION :
2007-11-20 09:51:44 +00:00
return ( ( zend_internal_function * ) EG ( current_execute_data ) - > function_state . function ) - > function_name ;
1999-04-07 18:10:10 +00:00
break ;
default :
2006-02-26 11:57:14 +00:00
return NULL_ZSTR ;
1999-04-07 18:10:10 +00:00
}
}
2007-07-11 11:19:58 +00:00
/* }}} */
1999-04-07 18:10:10 +00:00
2007-07-11 11:19:58 +00:00
ZEND_API char * zend_get_executed_filename ( TSRMLS_D ) /* { { { */
1999-04-07 18:10:10 +00:00
{
2000-08-09 19:22:35 +00:00
if ( EG ( active_op_array ) ) {
return EG ( active_op_array ) - > filename ;
1999-05-25 22:55:13 +00:00
} else {
return " [no active file] " ;
}
1999-04-07 18:10:10 +00:00
}
2007-07-11 11:19:58 +00:00
/* }}} */
1999-04-07 18:10:10 +00:00
2007-07-11 11:19:58 +00:00
ZEND_API uint zend_get_executed_lineno ( TSRMLS_D ) /* { { { */
1999-04-07 18:10:10 +00:00
{
1999-05-25 22:55:13 +00:00
if ( EG ( opline_ptr ) ) {
return active_opline - > lineno ;
} else {
return 0 ;
}
1999-04-07 18:10:10 +00:00
}
2007-07-11 11:19:58 +00:00
/* }}} */
1999-04-07 18:10:10 +00:00
2007-07-11 11:19:58 +00:00
ZEND_API zend_bool zend_is_executing ( TSRMLS_D ) /* { { { */
2000-02-04 14:45:58 +00:00
{
return EG ( in_execution ) ;
}
2007-07-11 11:19:58 +00:00
/* }}} */
2000-02-04 14:45:58 +00:00
2007-07-11 11:19:58 +00:00
ZEND_API void _zval_ptr_dtor ( zval * * zval_ptr ZEND_FILE_LINE_DC ) /* { { { */
1999-04-07 18:10:10 +00:00
{
# if DEBUG_ZEND>=2
2007-11-02 00:15:13 +00:00
printf ( " Reducing refcount for %x (%x): %d->%d \n " , * zval_ptr , zval_ptr , Z_REFCOUNT_PP ( zval_ptr ) , Z_REFCOUNT_PP ( zval_ptr ) - 1 ) ;
1999-04-07 18:10:10 +00:00
# endif
2007-10-07 05:15:07 +00:00
Z_DELREF_PP ( zval_ptr ) ;
if ( Z_REFCOUNT_PP ( zval_ptr ) = = 0 ) {
2008-05-06 16:02:50 +00:00
TSRMLS_FETCH ( ) ;
if ( * zval_ptr ! = & EG ( uninitialized_zval ) ) {
GC_REMOVE_ZVAL_FROM_BUFFER ( * zval_ptr ) ;
zval_dtor ( * zval_ptr ) ;
efree_rel ( * zval_ptr ) ;
}
2008-01-22 09:29:29 +00:00
} else {
TSRMLS_FETCH ( ) ;
if ( Z_REFCOUNT_PP ( zval_ptr ) = = 1 ) {
Z_UNSET_ISREF_PP ( zval_ptr ) ;
}
GC_ZVAL_CHECK_POSSIBLE_ROOT ( * zval_ptr ) ;
1999-04-07 18:10:10 +00:00
}
}
2007-07-11 11:19:58 +00:00
/* }}} */
2003-08-07 07:37:19 +00:00
2007-07-11 11:19:58 +00:00
ZEND_API void _zval_internal_ptr_dtor ( zval * * zval_ptr ZEND_FILE_LINE_DC ) /* { { { */
2003-08-24 17:32:47 +00:00
{
# if DEBUG_ZEND>=2
2007-11-02 00:15:13 +00:00
printf ( " Reducing refcount for %x (%x): %d->%d \n " , * zval_ptr , zval_ptr , Z_REFCOUNT_PP ( zval_ptr ) , Z_REFCOUNT_PP ( zval_ptr ) - 1 ) ;
2003-08-24 17:32:47 +00:00
# endif
2007-10-07 05:15:07 +00:00
Z_DELREF_PP ( zval_ptr ) ;
if ( Z_REFCOUNT_PP ( zval_ptr ) = = 0 ) {
2003-08-24 17:32:47 +00:00
zval_internal_dtor ( * zval_ptr ) ;
free ( * zval_ptr ) ;
2007-10-07 05:15:07 +00:00
} else if ( Z_REFCOUNT_PP ( zval_ptr ) = = 1 ) {
Z_UNSET_ISREF_PP ( zval_ptr ) ;
2003-08-24 17:32:47 +00:00
}
}
2007-07-11 11:19:58 +00:00
/* }}} */
2003-08-24 17:32:47 +00:00
2007-07-11 11:19:58 +00:00
ZEND_API int zend_is_true ( zval * op ) /* { { { */
1999-04-07 18:10:10 +00:00
{
return i_zend_is_true ( op ) ;
}
2007-07-11 11:19:58 +00:00
/* }}} */
1999-04-07 18:10:10 +00:00
2001-11-30 16:29:47 +00:00
# include "../TSRM/tsrm_strtok_r.h"
1999-04-07 18:10:10 +00:00
2007-11-02 00:15:13 +00:00
# define IS_VISITED_CONSTANT IS_CONSTANT_INDEX
# define IS_CONSTANT_VISITED(p) (Z_TYPE_P(p) & IS_VISITED_CONSTANT)
# define Z_REAL_TYPE_P(p) (Z_TYPE_P(p) & ~IS_VISITED_CONSTANT)
# define MARK_CONSTANT_VISITED(p) Z_TYPE_P(p) |= IS_VISITED_CONSTANT
2007-06-13 16:48:29 +00:00
2008-03-04 11:44:15 +00:00
static void zval_deep_copy ( zval * * p )
{
zval * value ;
ALLOC_ZVAL ( value ) ;
* value = * * p ;
Z_TYPE_P ( value ) & = ~ IS_CONSTANT_INDEX ;
zval_copy_ctor ( value ) ;
Z_TYPE_P ( value ) = Z_TYPE_PP ( p ) ;
INIT_PZVAL ( value ) ;
* p = value ;
}
2007-07-11 11:19:58 +00:00
ZEND_API int zval_update_constant_ex ( zval * * pp , void * arg , zend_class_entry * scope TSRMLS_DC ) /* { { { */
1999-04-07 18:10:10 +00:00
{
1999-11-21 18:11:10 +00:00
zval * p = * pp ;
2007-04-16 09:43:53 +00:00
zend_bool inline_change = ( zend_bool ) ( zend_uintptr_t ) arg ;
2001-07-16 11:41:06 +00:00
zval const_value ;
2007-06-13 14:50:33 +00:00
zstr colon ;
1999-11-21 18:11:10 +00:00
2007-06-13 16:48:29 +00:00
if ( IS_CONSTANT_VISITED ( p ) ) {
2007-06-27 11:16:21 +00:00
zend_error ( E_ERROR , " Cannot declare self-referencing constant '%v' " , Z_UNIVAL_P ( p ) ) ;
2007-08-24 13:50:52 +00:00
} else if ( ( Z_TYPE_P ( p ) & IS_CONSTANT_TYPE_MASK ) = = IS_CONSTANT ) {
2000-04-26 22:10:06 +00:00
int refcount ;
2005-06-08 13:21:28 +00:00
zend_uchar is_ref ;
2000-04-26 22:10:06 +00:00
2005-06-08 13:21:28 +00:00
SEPARATE_ZVAL_IF_NOT_REF ( pp ) ;
2000-04-26 22:10:06 +00:00
p = * pp ;
2007-06-13 16:48:29 +00:00
MARK_CONSTANT_VISITED ( p ) ;
2007-10-07 05:15:07 +00:00
refcount = Z_REFCOUNT_P ( p ) ;
is_ref = Z_ISREF_P ( p ) ;
1999-04-07 18:10:10 +00:00
2009-03-26 20:02:53 +00:00
if ( ! zend_u_get_constant_ex ( IS_UNICODE , Z_UNIVAL_P ( p ) , Z_UNILEN_P ( p ) , & const_value , scope , Z_REAL_TYPE_P ( p ) TSRMLS_CC ) ) {
2008-12-04 20:12:30 +00:00
zstr actual = Z_UNIVAL_P ( p ) ;
2009-03-26 20:02:53 +00:00
if ( ( colon . u = u_memrchr ( Z_USTRVAL_P ( p ) , ' : ' , Z_USTRLEN_P ( p ) ) ) & & colon . u > Z_USTRVAL_P ( p ) & & * ( colon . u - 1 ) = = ' : ' ) {
2008-12-04 20:12:30 +00:00
zend_error ( E_ERROR , " Undefined class constant '%v' " , actual ) ;
} else {
zstr save = actual , slash ;
int actual_len = Z_UNILEN_P ( p ) ;
2009-03-26 20:02:53 +00:00
if ( IS_UNICODE = = IS_UNICODE ) {
2008-12-04 20:12:30 +00:00
slash . u = u_memrchr ( actual . u , ' \\ ' , actual_len ) ;
2007-11-02 00:15:13 +00:00
} else {
2008-12-04 20:12:30 +00:00
slash . s = zend_memrchr ( actual . s , ' \\ ' , actual_len ) ;
2007-11-02 00:15:13 +00:00
}
2008-12-04 20:12:30 +00:00
if ( ( Z_TYPE_P ( p ) & IS_CONSTANT_UNQUALIFIED ) & & slash . v ! = NULL ) {
2009-03-26 20:02:53 +00:00
if ( IS_UNICODE = = IS_UNICODE ) {
2008-12-04 20:12:30 +00:00
actual . u = slash . u + 1 ;
actual_len - = ( actual . u - Z_USTRVAL_P ( p ) ) ;
} else {
actual . s = slash . s + 1 ;
actual_len - = ( actual . s - Z_STRVAL_P ( p ) ) ;
}
if ( inline_change ) {
int type = Z_TYPE_P ( p ) ;
2009-03-26 20:02:53 +00:00
ZVAL_ZSTRL ( p , IS_UNICODE , actual , actual_len , 1 ) ;
2008-12-04 20:12:30 +00:00
Z_TYPE_P ( p ) = type ;
actual = Z_UNIVAL_P ( p ) ;
}
2007-12-07 17:12:22 +00:00
}
2009-03-26 20:02:53 +00:00
if ( IS_UNICODE = = IS_UNICODE & & actual . u [ 0 ] = = ' \\ ' ) {
2007-12-07 17:12:22 +00:00
if ( inline_change ) {
2008-12-04 20:12:30 +00:00
memmove ( Z_USTRVAL_P ( p ) , Z_USTRVAL_P ( p ) + 1 , UBYTES ( Z_USTRLEN_P ( p ) ) ) ;
- - Z_USTRLEN_P ( p ) ;
2007-12-07 17:12:22 +00:00
} else {
2008-12-04 20:12:30 +00:00
+ + actual . u ;
2007-12-07 17:12:22 +00:00
}
2008-12-04 20:12:30 +00:00
- - actual_len ;
2009-03-26 20:02:53 +00:00
} else if ( IS_UNICODE = = IS_STRING & & actual . s [ 0 ] = = ' \\ ' ) {
2007-12-07 17:12:22 +00:00
if ( inline_change ) {
2008-12-04 20:12:30 +00:00
memmove ( Z_STRVAL_P ( p ) , Z_STRVAL_P ( p ) + 1 , Z_STRLEN_P ( p ) ) ;
- - Z_STRLEN_P ( p ) ;
2007-12-07 17:12:22 +00:00
} else {
2008-12-04 20:12:30 +00:00
+ + actual . s ;
2007-12-07 17:12:22 +00:00
}
2008-12-04 20:12:30 +00:00
- - actual_len ;
}
if ( ( Z_TYPE_P ( p ) & IS_CONSTANT_UNQUALIFIED ) = = 0 ) {
int fix_save = 0 ;
2009-03-26 20:02:53 +00:00
if ( IS_UNICODE = = IS_UNICODE & & save . u [ 0 ] = = ' \\ ' ) {
2008-12-04 20:12:30 +00:00
save . u + + ;
fix_save = 1 ;
2009-03-26 20:02:53 +00:00
} else if ( IS_UNICODE = = IS_STRING & & save . s [ 0 ] = = ' \\ ' ) {
2008-12-04 20:12:30 +00:00
save . s + + ;
fix_save = 1 ;
}
zend_error ( E_ERROR , " Undefined constant '%v' " , save ) ;
if ( fix_save ) {
2009-03-26 20:02:53 +00:00
- - save . u ;
2008-12-04 20:12:30 +00:00
}
if ( inline_change ) {
efree ( save . v ) ;
}
save . v = NULL ;
}
if ( inline_change & & save . v & & save . v ! = actual . v ) {
efree ( save . v ) ;
}
zend_error ( E_NOTICE , " Use of undefined constant %v - assumed '%v' " , actual , actual ) ;
2009-03-26 20:02:53 +00:00
Z_TYPE_P ( p ) = IS_UNICODE ;
2008-12-04 20:12:30 +00:00
if ( ! inline_change ) {
ZVAL_ZSTRL ( p , Z_TYPE_P ( p ) , actual , actual_len , 0 ) ;
zval_copy_ctor ( p ) ;
2007-12-07 17:12:22 +00:00
}
2001-11-30 16:29:47 +00:00
}
2003-06-15 14:46:15 +00:00
} else {
2000-05-31 19:07:09 +00:00
if ( inline_change ) {
2006-02-20 19:03:43 +00:00
STR_FREE ( Z_STRVAL_P ( p ) ) ;
2000-05-31 19:07:09 +00:00
}
2001-07-16 11:41:06 +00:00
* p = const_value ;
1999-04-07 18:10:10 +00:00
}
2003-06-15 14:46:15 +00:00
2007-10-07 05:15:07 +00:00
Z_SET_REFCOUNT_P ( p , refcount ) ;
Z_SET_ISREF_TO_P ( p , is_ref ) ;
2006-02-20 19:03:43 +00:00
} else if ( Z_TYPE_P ( p ) = = IS_CONSTANT_ARRAY ) {
2003-06-09 17:02:32 +00:00
zval * * element , * new_val ;
2006-02-21 20:12:43 +00:00
zstr str_index ;
2001-08-21 12:29:12 +00:00
uint str_index_len ;
ulong num_index ;
2008-08-26 08:38:15 +00:00
int ret ;
2001-07-16 11:41:06 +00:00
2005-06-08 13:21:28 +00:00
SEPARATE_ZVAL_IF_NOT_REF ( pp ) ;
2000-04-26 22:10:06 +00:00
p = * pp ;
2006-02-20 19:03:43 +00:00
Z_TYPE_P ( p ) = IS_ARRAY ;
2003-08-07 07:37:19 +00:00
2008-03-04 11:44:15 +00:00
if ( ! inline_change ) {
zval * tmp ;
HashTable * tmp_ht = NULL ;
ALLOC_HASHTABLE ( tmp_ht ) ;
zend_hash_init ( tmp_ht , zend_hash_num_elements ( Z_ARRVAL_P ( p ) ) , NULL , ZVAL_PTR_DTOR , 0 ) ;
zend_hash_copy ( tmp_ht , Z_ARRVAL_P ( p ) , ( copy_ctor_func_t ) zval_deep_copy , ( void * ) & tmp , sizeof ( zval * ) ) ;
Z_ARRVAL_P ( p ) = tmp_ht ;
}
2001-07-16 11:41:06 +00:00
/* First go over the array and see if there are any constant indices */
2006-02-20 19:03:43 +00:00
zend_hash_internal_pointer_reset ( Z_ARRVAL_P ( p ) ) ;
2007-11-02 00:15:13 +00:00
while ( zend_hash_get_current_data ( Z_ARRVAL_P ( p ) , ( void * * ) & element ) = = SUCCESS ) {
2001-07-16 11:41:06 +00:00
if ( ! ( Z_TYPE_PP ( element ) & IS_CONSTANT_INDEX ) ) {
2006-02-20 19:03:43 +00:00
zend_hash_move_forward ( Z_ARRVAL_P ( p ) ) ;
2001-07-16 11:41:06 +00:00
continue ;
}
Z_TYPE_PP ( element ) & = ~ IS_CONSTANT_INDEX ;
2009-03-26 20:02:53 +00:00
if ( zend_hash_get_current_key_ex ( Z_ARRVAL_P ( p ) , & str_index , & str_index_len , & num_index , 0 , NULL ) ! = HASH_KEY_IS_UNICODE ) {
2006-02-20 19:03:43 +00:00
zend_hash_move_forward ( Z_ARRVAL_P ( p ) ) ;
2001-07-16 11:41:06 +00:00
continue ;
}
2009-03-26 20:02:53 +00:00
if ( ! zend_u_get_constant_ex ( IS_UNICODE , str_index , str_index_len - 3 , & const_value , scope , str_index . u [ str_index_len - 2 ] TSRMLS_CC ) ) {
UChar * actual , * save = str_index . u ;
if ( ( colon . u = u_memrchr ( str_index . u , ' : ' , str_index_len - 3 ) ) & & colon . u > str_index . u & & * ( colon . u - 1 ) = = ' : ' ) {
zend_error ( E_ERROR , " Undefined class constant '%v' " , str_index ) ;
str_index_len - = ( ( colon . u - str_index . u ) + 1 ) ;
str_index . u = colon . u + 1 ;
2007-12-07 17:12:22 +00:00
} else {
2009-03-26 20:02:53 +00:00
if ( str_index . u [ str_index_len - 2 ] & IS_CONSTANT_UNQUALIFIED ) {
if ( ( actual = ( UChar * ) u_memrchr ( str_index . u , ' \\ ' , str_index_len - 3 ) ) ) {
actual + + ;
str_index_len - = ( actual - str_index . u ) ;
str_index . u = actual ;
}
}
if ( str_index . u [ 0 ] = = ' \\ ' ) {
+ + str_index . u ;
- - str_index_len ;
}
if ( save [ 0 ] = = ' \\ ' ) {
+ + save ;
}
if ( ( str_index . u [ str_index_len - 2 ] & IS_CONSTANT_UNQUALIFIED ) = = 0 ) {
zend_error ( E_ERROR , " Undefined constant '%r' " , save ) ;
2007-12-07 17:12:22 +00:00
}
2007-06-13 14:50:33 +00:00
}
2005-08-19 13:20:16 +00:00
zend_error ( E_NOTICE , " Use of undefined constant %v - assumed '%v' " , str_index , str_index ) ;
2009-05-25 14:32:15 +00:00
ZVAL_UNICODEL ( & const_value , str_index . u , str_index_len - 3 , 1 ) ;
2001-07-16 11:41:06 +00:00
}
2003-08-07 07:37:19 +00:00
2007-11-02 10:11:59 +00:00
if ( Z_REFCOUNT_PP ( element ) > 1 ) {
ALLOC_ZVAL ( new_val ) ;
* new_val = * * element ;
zval_copy_ctor ( new_val ) ;
Z_SET_REFCOUNT_P ( new_val , 1 ) ;
Z_UNSET_ISREF_P ( new_val ) ;
/* preserve this bit for inheritance */
Z_TYPE_PP ( element ) | = IS_CONSTANT_INDEX ;
zval_ptr_dtor ( element ) ;
* element = new_val ;
2005-08-11 23:35:03 +00:00
}
2002-09-10 08:35:50 +00:00
2006-02-20 19:03:43 +00:00
switch ( Z_TYPE ( const_value ) ) {
2005-12-05 08:56:32 +00:00
case IS_STRING :
case IS_UNICODE :
2008-08-26 08:38:15 +00:00
ret = zend_u_symtable_update_current_key ( Z_ARRVAL_P ( p ) , Z_TYPE ( const_value ) , Z_UNIVAL ( const_value ) , Z_UNILEN ( const_value ) + 1 , HASH_UPDATE_KEY_IF_BEFORE ) ;
2005-08-11 23:35:03 +00:00
break ;
2005-02-12 16:38:47 +00:00
case IS_BOOL :
2001-07-16 11:41:06 +00:00
case IS_LONG :
2008-08-26 08:38:15 +00:00
ret = zend_hash_update_current_key_ex ( Z_ARRVAL_P ( p ) , HASH_KEY_IS_LONG , NULL_ZSTR , 0 , Z_LVAL ( const_value ) , HASH_UPDATE_KEY_IF_BEFORE , NULL ) ;
2005-07-07 15:16:57 +00:00
break ;
case IS_DOUBLE :
2009-06-04 18:18:47 +00:00
ret = zend_hash_update_current_key_ex ( Z_ARRVAL_P ( p ) , HASH_KEY_IS_LONG , NULL_ZSTR , 0 , zend_dval_to_lval ( Z_DVAL ( const_value ) ) , HASH_UPDATE_KEY_IF_BEFORE , NULL ) ;
2005-07-07 15:16:57 +00:00
break ;
case IS_NULL :
2008-08-26 08:38:15 +00:00
ret = zend_hash_update_current_key_ex ( Z_ARRVAL_P ( p ) , HASH_KEY_IS_STRING , EMPTY_ZSTR , 1 , 0 , HASH_UPDATE_KEY_IF_BEFORE , NULL ) ;
2001-07-16 11:41:06 +00:00
break ;
2008-08-26 08:38:15 +00:00
default :
ret = SUCCESS ;
break ;
}
if ( ret = = SUCCESS ) {
zend_hash_move_forward ( Z_ARRVAL_P ( p ) ) ;
2001-07-16 11:41:06 +00:00
}
2002-09-10 08:35:50 +00:00
zval_dtor ( & const_value ) ;
2001-07-16 11:41:06 +00:00
}
2006-02-20 19:03:43 +00:00
zend_hash_apply_with_argument ( Z_ARRVAL_P ( p ) , ( apply_func_arg_t ) zval_update_constant , ( void * ) 1 TSRMLS_CC ) ;
zend_hash_internal_pointer_reset ( Z_ARRVAL_P ( p ) ) ;
1999-04-07 18:10:10 +00:00
}
1999-11-21 18:11:10 +00:00
return 0 ;
1999-04-07 18:10:10 +00:00
}
2007-07-11 11:19:58 +00:00
/* }}} */
1999-04-07 18:10:10 +00:00
2007-07-11 11:19:58 +00:00
ZEND_API int zval_update_constant ( zval * * pp , void * arg TSRMLS_DC ) /* { { { */
2006-10-18 16:34:25 +00:00
{
2006-10-18 17:03:26 +00:00
return zval_update_constant_ex ( pp , arg , NULL TSRMLS_CC ) ;
2006-10-18 16:34:25 +00:00
}
2007-07-11 11:19:58 +00:00
/* }}} */
1999-08-06 15:24:10 +00:00
2007-07-11 11:19:58 +00:00
int call_user_function ( HashTable * function_table , zval * * object_pp , zval * function_name , zval * retval_ptr , zend_uint param_count , zval * params [ ] TSRMLS_DC ) /* { { { */
1999-08-06 15:24:10 +00:00
{
2004-07-18 09:55:02 +00:00
zval * * * params_array ;
ntroduce infrastructure for supplying information about arguments,
including:
- Whether or not to pass by ref (replaces the old arg_types, with arg_info)
- Argument name (for future use, maybe introspection)
- Class/Interface name (for type hints)
- If a class/interface name is available, whether to allow a null instance
Both user and builtin functions share the same data structures.
To declare a builtin function that expects its first arg to be an instance
of class 'Person', its second argument as a regular arg, and its third by
reference, use:
ZEND_BEGIN_ARG_INFO(my_func_arg_info, 0)
ZEND_ARG_OBJ_INFO(0, someone, Person, 1)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
ZEND_END_ARG_INFO();
and use my_func_arg_info as the arg_info parameter to the ZEND_FE() family
of macros.
The first arg to each ZEND_ARG_*() macro is whether or not to pass by ref.
The boolean arg to ZEND_BEGIN_ARG_INFO() tells the engine whether to treat
the arguments for which there's no explicit information as pass by reference
or not.
The boolean argument to ZEND_ARG_OBJ_INFO() (4th arg) is whether or not to allownull values.
2003-08-03 17:40:44 +00:00
zend_uint i ;
1999-08-06 15:24:10 +00:00
int ex_retval ;
2005-07-26 18:33:15 +00:00
zval * local_retval_ptr = NULL ;
1999-08-06 15:24:10 +00:00
2004-07-18 09:55:02 +00:00
if ( param_count ) {
params_array = ( zval * * * ) emalloc ( sizeof ( zval * * ) * param_count ) ;
for ( i = 0 ; i < param_count ; i + + ) {
params_array [ i ] = & params [ i ] ;
}
} else {
params_array = NULL ;
1999-08-06 15:24:10 +00:00
}
2001-07-30 07:43:02 +00:00
ex_retval = call_user_function_ex ( function_table , object_pp , function_name , & local_retval_ptr , param_count , params_array , 1 , NULL TSRMLS_CC ) ;
1999-12-19 18:54:40 +00:00
if ( local_retval_ptr ) {
COPY_PZVAL_TO_ZVAL ( * retval_ptr , local_retval_ptr ) ;
} else {
INIT_ZVAL ( * retval_ptr ) ;
}
2004-07-18 09:55:02 +00:00
if ( params_array ) {
efree ( params_array ) ;
}
1999-08-06 15:24:10 +00:00
return ex_retval ;
}
2007-07-11 11:19:58 +00:00
/* }}} */
1999-08-06 15:24:10 +00:00
2007-07-11 11:19:58 +00:00
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 ) /* { { { */
2003-05-20 16:44:42 +00:00
{
2003-08-05 10:24:40 +00:00
zend_fcall_info fci ;
fci . size = sizeof ( fci ) ;
fci . function_table = function_table ;
2008-11-27 19:02:45 +00:00
fci . object_ptr = object_pp ? * object_pp : NULL ;
2003-08-05 10:24:40 +00:00
fci . function_name = function_name ;
fci . retval_ptr_ptr = retval_ptr_ptr ;
fci . param_count = param_count ;
fci . params = params ;
fci . no_separation = ( zend_bool ) no_separation ;
fci . symbol_table = symbol_table ;
return zend_call_function ( & fci , NULL TSRMLS_CC ) ;
2003-05-20 16:44:42 +00:00
}
2007-07-11 11:19:58 +00:00
/* }}} */
2003-05-20 16:44:42 +00:00
2007-07-11 11:19:58 +00:00
int zend_call_function ( zend_fcall_info * fci , zend_fcall_info_cache * fci_cache TSRMLS_DC ) /* { { { */
1999-04-07 18:10:10 +00:00
{
ntroduce infrastructure for supplying information about arguments,
including:
- Whether or not to pass by ref (replaces the old arg_types, with arg_info)
- Argument name (for future use, maybe introspection)
- Class/Interface name (for type hints)
- If a class/interface name is available, whether to allow a null instance
Both user and builtin functions share the same data structures.
To declare a builtin function that expects its first arg to be an instance
of class 'Person', its second argument as a regular arg, and its third by
reference, use:
ZEND_BEGIN_ARG_INFO(my_func_arg_info, 0)
ZEND_ARG_OBJ_INFO(0, someone, Person, 1)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
ZEND_END_ARG_INFO();
and use my_func_arg_info as the arg_info parameter to the ZEND_FE() family
of macros.
The first arg to each ZEND_ARG_*() macro is whether or not to pass by ref.
The boolean arg to ZEND_BEGIN_ARG_INFO() tells the engine whether to treat
the arguments for which there's no explicit information as pass by reference
or not.
The boolean argument to ZEND_ARG_OBJ_INFO() (4th arg) is whether or not to allownull values.
2003-08-03 17:40:44 +00:00
zend_uint i ;
1999-12-19 18:54:40 +00:00
zval * * original_return_value ;
1999-04-07 18:10:10 +00:00
HashTable * calling_symbol_table ;
zend_op_array * original_op_array ;
zend_op * * original_opline_ptr ;
2002-03-01 14:27:26 +00:00
zend_class_entry * current_scope ;
2007-09-26 07:16:33 +00:00
zend_class_entry * current_called_scope ;
2002-03-01 14:27:26 +00:00
zend_class_entry * calling_scope = NULL ;
2008-07-24 10:14:01 +00:00
zend_class_entry * called_scope = NULL ;
2002-01-05 15:18:30 +00:00
zval * current_this ;
2002-08-23 13:50:42 +00:00
zend_execute_data execute_data ;
2005-08-11 23:35:03 +00:00
char * old_func_name = NULL ;
2002-08-23 13:50:42 +00:00
2007-04-27 08:11:37 +00:00
* fci - > retval_ptr_ptr = NULL ;
2006-09-11 14:28:19 +00:00
if ( ! EG ( active ) ) {
return FAILURE ; /* executor is already inactive */
}
2005-03-19 14:25:42 +00:00
if ( EG ( exception ) ) {
return FAILURE ; /* we would result in an instable executor otherwise */
}
2003-08-05 10:24:40 +00:00
switch ( fci - > size ) {
case sizeof ( zend_fcall_info ) :
break ; /* nothing to do currently */
default :
zend_error ( E_ERROR , " Corrupted fcall_info provided to zend_call_function() " ) ;
break ;
}
2002-08-23 13:50:42 +00:00
/* Initialize execute_data */
2004-02-04 23:48:39 +00:00
if ( EG ( current_execute_data ) ) {
execute_data = * EG ( current_execute_data ) ;
2005-06-22 15:26:05 +00:00
EX ( op_array ) = NULL ;
EX ( opline ) = NULL ;
2007-11-02 00:15:13 +00:00
EX ( object ) = NULL ;
2004-02-04 23:48:39 +00:00
} else {
2004-02-11 13:01:39 +00:00
/* This only happens when we're called outside any execute()'s
* It shouldn ' t be strictly necessary to NULL execute_data out ,
* but it may make bugs easier to spot
*/
2004-02-04 23:48:39 +00:00
memset ( & execute_data , 0 , sizeof ( zend_execute_data ) ) ;
}
2000-01-15 22:52:24 +00:00
2003-08-05 10:24:40 +00:00
if ( ! fci_cache | | ! fci_cache - > initialized ) {
2008-07-26 13:14:56 +00:00
zend_fcall_info_cache fci_cache_local ;
zval callable_name ;
char * error = NULL ;
if ( ! fci_cache ) {
fci_cache = & fci_cache_local ;
}
2008-11-27 19:02:45 +00:00
if ( ! zend_is_callable_ex ( fci - > function_name , fci - > object_ptr , IS_CALLABLE_CHECK_SILENT , & callable_name , fci_cache , & error TSRMLS_CC ) ) {
2008-07-26 13:14:56 +00:00
if ( error ) {
zend_error ( E_WARNING , " Invalid callback %Z, %s " , callable_name , error ) ;
efree ( error ) ;
}
zval_dtor ( & callable_name ) ;
return FAILURE ;
} else if ( error ) {
/* Capitalize the first latter of the error message */
if ( error [ 0 ] > = ' a ' & & error [ 0 ] < = ' z ' ) {
error [ 0 ] + = ( ' A ' - ' a ' ) ;
}
zend_error ( E_STRICT , " %s " , error ) ;
efree ( error ) ;
}
zval_dtor ( & callable_name ) ;
}
EX ( function_state ) . function = fci_cache - > function_handler ;
calling_scope = fci_cache - > calling_scope ;
called_scope = fci_cache - > called_scope ;
2008-11-27 19:02:45 +00:00
fci - > object_ptr = fci_cache - > object_ptr ;
EX ( object ) = fci - > object_ptr ;
if ( fci - > object_ptr & & Z_TYPE_P ( fci - > object_ptr ) = = IS_OBJECT
& & ( ! EG ( objects_store ) . object_buckets | | ! EG ( objects_store ) . object_buckets [ Z_OBJ_HANDLE_P ( fci - > object_ptr ) ] . valid ) ) {
2008-07-26 13:14:56 +00:00
return FAILURE ;
1999-04-07 18:10:10 +00:00
}
2006-02-21 08:00:39 +00:00
if ( EX ( function_state ) . function - > common . fn_flags & ( ZEND_ACC_ABSTRACT | ZEND_ACC_DEPRECATED ) ) {
2006-02-20 20:03:36 +00:00
if ( EX ( function_state ) . function - > common . fn_flags & ZEND_ACC_ABSTRACT ) {
zend_error_noreturn ( E_ERROR , " Cannot call abstract method %v::%v() " , EX ( function_state ) . function - > common . scope - > name , EX ( function_state ) . function - > common . function_name ) ;
}
2006-02-21 08:00:39 +00:00
if ( EX ( function_state ) . function - > common . fn_flags & ZEND_ACC_DEPRECATED ) {
2008-02-23 17:03:53 +00:00
zend_error ( E_DEPRECATED , " Function %v%s%v() is deprecated " ,
2006-02-26 11:57:14 +00:00
EX ( function_state ) . function - > common . scope ? EX ( function_state ) . function - > common . scope - > name : EMPTY_ZSTR ,
2006-02-20 20:03:36 +00:00
EX ( function_state ) . function - > common . scope ? " :: " : " " ,
EX ( function_state ) . function - > common . function_name ) ;
}
2006-02-20 20:00:46 +00:00
}
2009-06-15 14:06:30 +00:00
ZEND_VM_STACK_GROW_IF_NEEDED ( ( int ) ( fci - > param_count + 1 ) ) ;
2008-01-24 09:41:48 +00:00
2003-08-05 10:24:40 +00:00
for ( i = 0 ; i < fci - > param_count ; i + + ) {
1999-04-07 18:10:10 +00:00
zval * param ;
2009-08-18 20:51:49 +00:00
if ( EX ( function_state ) . function - > type = = ZEND_INTERNAL_FUNCTION
& & ! ARG_SHOULD_BE_SENT_BY_REF ( EX ( function_state ) . function , i + 1 )
& & PZVAL_IS_REF ( * fci - > params [ i ] ) ) {
SEPARATE_ZVAL ( fci - > params [ i ] ) ;
}
2007-11-02 00:15:13 +00:00
if ( ARG_SHOULD_BE_SENT_BY_REF ( EX ( function_state ) . function , i + 1 )
2003-08-05 10:24:40 +00:00
& & ! PZVAL_IS_REF ( * fci - > params [ i ] ) ) {
2007-10-07 05:15:07 +00:00
if ( Z_REFCOUNT_PP ( fci - > params [ i ] ) > 1 ) {
1999-08-06 15:24:10 +00:00
zval * new_zval ;
2003-08-05 10:24:40 +00:00
if ( fci - > no_separation ) {
2005-05-18 18:02:50 +00:00
if ( i ) {
/* hack to clean up the stack */
2008-01-24 09:41:48 +00:00
zend_vm_stack_push_nocheck ( ( void * ) ( zend_uintptr_t ) i TSRMLS_CC ) ;
zend_vm_stack_clear_multiple ( TSRMLS_C ) ;
2005-05-18 18:02:50 +00:00
}
2005-08-22 12:22:16 +00:00
if ( old_func_name ) {
efree ( Z_STRVAL_P ( fci - > function_name ) ) ;
Z_TYPE_P ( fci - > function_name ) = IS_STRING ;
Z_STRVAL_P ( fci - > function_name ) = old_func_name ;
}
2006-12-21 11:07:41 +00:00
2008-01-10 09:38:41 +00:00
zend_error ( E_WARNING , " Parameter %d to %v%s%v() expected to be a reference, value given " ,
i + 1 ,
EX ( function_state ) . function - > common . scope ? EX ( function_state ) . function - > common . scope - > name : EMPTY_ZSTR ,
EX ( function_state ) . function - > common . scope ? " :: " : " " ,
EX ( function_state ) . function - > common . function_name ) ;
1999-08-06 15:24:10 +00:00
return FAILURE ;
}
1999-12-26 21:21:33 +00:00
ALLOC_ZVAL ( new_zval ) ;
2003-08-05 10:24:40 +00:00
* new_zval = * * fci - > params [ i ] ;
1999-08-06 21:43:49 +00:00
zval_copy_ctor ( new_zval ) ;
2007-10-07 05:15:07 +00:00
Z_SET_REFCOUNT_P ( new_zval , 1 ) ;
Z_DELREF_PP ( fci - > params [ i ] ) ;
2003-08-05 10:24:40 +00:00
* fci - > params [ i ] = new_zval ;
1999-08-06 15:24:10 +00:00
}
2007-10-07 05:15:07 +00:00
Z_ADDREF_PP ( fci - > params [ i ] ) ;
Z_SET_ISREF_PP ( fci - > params [ i ] ) ;
2003-08-05 10:24:40 +00:00
param = * fci - > params [ i ] ;
} else if ( * fci - > params [ i ] ! = & EG ( uninitialized_zval ) ) {
2007-10-07 05:15:07 +00:00
Z_ADDREF_PP ( fci - > params [ i ] ) ;
2003-08-05 10:24:40 +00:00
param = * fci - > params [ i ] ;
1999-08-06 15:24:10 +00:00
} else {
1999-12-26 21:21:33 +00:00
ALLOC_ZVAL ( param ) ;
2003-08-05 10:24:40 +00:00
* param = * * ( fci - > params [ i ] ) ;
1999-08-06 15:24:10 +00:00
INIT_PZVAL ( param ) ;
}
2008-07-26 13:14:56 +00:00
zend_vm_stack_push_nocheck ( param TSRMLS_CC ) ;
1999-04-07 18:10:10 +00:00
}
2008-01-24 09:41:48 +00:00
EX ( function_state ) . arguments = zend_vm_stack_top ( TSRMLS_C ) ;
zend_vm_stack_push_nocheck ( ( void * ) ( zend_uintptr_t ) fci - > param_count TSRMLS_CC ) ;
1999-04-07 18:10:10 +00:00
2002-03-01 14:27:26 +00:00
current_scope = EG ( scope ) ;
EG ( scope ) = calling_scope ;
2001-12-26 20:17:34 +00:00
2002-03-01 14:27:26 +00:00
current_this = EG ( This ) ;
2002-01-05 15:18:30 +00:00
2007-09-26 07:16:33 +00:00
current_called_scope = EG ( called_scope ) ;
2008-07-24 10:14:01 +00:00
if ( called_scope ) {
EG ( called_scope ) = called_scope ;
2007-09-26 07:16:33 +00:00
} else if ( EX ( function_state ) . function - > type ! = ZEND_INTERNAL_FUNCTION ) {
EG ( called_scope ) = NULL ;
}
2007-11-02 00:15:13 +00:00
2008-11-27 19:02:45 +00:00
if ( fci - > object_ptr ) {
2004-03-16 14:59:06 +00:00
if ( ( EX ( function_state ) . function - > common . fn_flags & ZEND_ACC_STATIC ) ) {
EG ( This ) = NULL ;
} else {
2008-11-27 19:02:45 +00:00
EG ( This ) = fci - > object_ptr ;
2002-01-14 16:55:23 +00:00
2004-03-16 14:49:52 +00:00
if ( ! PZVAL_IS_REF ( EG ( This ) ) ) {
2007-10-07 05:15:07 +00:00
Z_ADDREF_P ( EG ( This ) ) ; /* For $this pointer */
2004-03-16 14:49:52 +00:00
} else {
zval * this_ptr ;
2002-01-05 15:18:30 +00:00
2004-03-16 14:49:52 +00:00
ALLOC_ZVAL ( this_ptr ) ;
* this_ptr = * EG ( This ) ;
INIT_PZVAL ( this_ptr ) ;
zval_copy_ctor ( this_ptr ) ;
EG ( This ) = this_ptr ;
}
2002-01-05 15:18:30 +00:00
}
2002-01-14 16:55:23 +00:00
} else {
2002-03-01 14:27:26 +00:00
EG ( This ) = NULL ;
2002-01-05 15:18:30 +00:00
}
2002-08-23 13:50:42 +00:00
EX ( prev_execute_data ) = EG ( current_execute_data ) ;
EG ( current_execute_data ) = & execute_data ;
2002-01-05 15:18:30 +00:00
2002-08-23 13:50:42 +00:00
if ( EX ( function_state ) . function - > type = = ZEND_USER_FUNCTION ) {
1999-04-13 19:28:03 +00:00
calling_symbol_table = EG ( active_symbol_table ) ;
2003-09-11 17:04:26 +00:00
EG ( scope ) = EX ( function_state ) . function - > common . scope ;
2003-08-05 10:24:40 +00:00
if ( fci - > symbol_table ) {
EG ( active_symbol_table ) = fci - > symbol_table ;
2000-06-17 16:50:38 +00:00
} else {
2008-05-06 17:01:07 +00:00
EG ( active_symbol_table ) = NULL ;
2000-06-17 16:50:38 +00:00
}
2002-01-05 15:18:30 +00:00
1999-12-19 18:54:40 +00:00
original_return_value = EG ( return_value_ptr_ptr ) ;
1999-04-07 18:10:10 +00:00
original_op_array = EG ( active_op_array ) ;
2003-08-05 10:24:40 +00:00
EG ( return_value_ptr_ptr ) = fci - > retval_ptr_ptr ;
2002-08-23 13:50:42 +00:00
EG ( active_op_array ) = ( zend_op_array * ) EX ( function_state ) . function ;
1999-12-19 18:54:40 +00:00
original_opline_ptr = EG ( opline_ptr ) ;
2001-07-27 10:10:39 +00:00
zend_execute ( EG ( active_op_array ) TSRMLS_CC ) ;
2008-05-06 17:01:07 +00:00
if ( ! fci - > symbol_table & & EG ( active_symbol_table ) ) {
if ( EG ( symtable_cache_ptr ) > = EG ( symtable_cache_limit ) ) {
zend_hash_destroy ( EG ( active_symbol_table ) ) ;
FREE_HASHTABLE ( EG ( active_symbol_table ) ) ;
} else {
/* clean before putting into the cache, since clean
could call dtors , which could use cached hash */
zend_hash_clean ( EG ( active_symbol_table ) ) ;
* ( + + EG ( symtable_cache_ptr ) ) = EG ( active_symbol_table ) ;
}
2000-06-17 16:50:38 +00:00
}
1999-04-13 19:28:03 +00:00
EG ( active_symbol_table ) = calling_symbol_table ;
1999-04-07 18:10:10 +00:00
EG ( active_op_array ) = original_op_array ;
1999-12-19 18:54:40 +00:00
EG ( return_value_ptr_ptr ) = original_return_value ;
1999-04-07 18:10:10 +00:00
EG ( opline_ptr ) = original_opline_ptr ;
2008-07-26 17:01:59 +00:00
} else if ( EX ( function_state ) . function - > type = = ZEND_INTERNAL_FUNCTION ) {
2008-07-26 13:14:56 +00:00
int call_via_handler = ( EX ( function_state ) . function - > common . fn_flags & ZEND_ACC_CALL_VIA_HANDLER ) ! = 0 ;
2003-08-05 10:24:40 +00:00
ALLOC_INIT_ZVAL ( * fci - > retval_ptr_ptr ) ;
2003-09-11 17:06:53 +00:00
if ( EX ( function_state ) . function - > common . scope ) {
2003-09-11 17:04:26 +00:00
EG ( scope ) = EX ( function_state ) . function - > common . scope ;
}
2008-11-27 19:02:45 +00:00
( ( 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 ) ;
2007-02-08 14:47:32 +00:00
/* We shouldn't fix bad extensions here,
because it can break proper ones ( Bug # 34045 )
2007-02-08 12:30:40 +00:00
if ( ! EX ( function_state ) . function - > common . return_reference )
{
INIT_PZVAL ( * fci - > retval_ptr_ptr ) ;
2007-02-08 14:47:32 +00:00
} */
2008-01-14 18:14:00 +00:00
if ( EG ( exception ) & & fci - > retval_ptr_ptr ) {
zval_ptr_dtor ( fci - > retval_ptr_ptr ) ;
2008-01-15 11:47:29 +00:00
* fci - > retval_ptr_ptr = NULL ;
2008-01-14 18:14:00 +00:00
}
2008-07-26 13:14:56 +00:00
if ( call_via_handler ) {
/* We must re-initialize function again */
fci_cache - > initialized = 0 ;
}
2008-07-26 17:01:59 +00:00
} else { /* ZEND_OVERLOADED_FUNCTION */
ALLOC_INIT_ZVAL ( * fci - > retval_ptr_ptr ) ;
2008-08-08 17:10:49 +00:00
/* Not sure what should be done here if it's a static method */
2008-11-27 19:02:45 +00:00
if ( fci - > object_ptr ) {
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 ) ;
2008-07-26 17:01:59 +00:00
} else {
zend_error_noreturn ( E_ERROR , " Cannot call overloaded function for non-object " ) ;
}
if ( EX ( function_state ) . function - > type = = ZEND_OVERLOADED_FUNCTION_TEMPORARY ) {
efree ( EX ( function_state ) . function - > common . function_name . v ) ;
}
efree ( EX ( function_state ) . function ) ;
if ( EG ( exception ) & & fci - > retval_ptr_ptr ) {
zval_ptr_dtor ( fci - > retval_ptr_ptr ) ;
* fci - > retval_ptr_ptr = NULL ;
}
1999-04-07 18:10:10 +00:00
}
2008-01-24 09:41:48 +00:00
zend_vm_stack_clear_multiple ( TSRMLS_C ) ;
1999-04-07 18:10:10 +00:00
2002-03-01 14:27:26 +00:00
if ( EG ( This ) ) {
zval_ptr_dtor ( & EG ( This ) ) ;
2002-01-05 15:18:30 +00:00
}
2007-09-26 07:16:33 +00:00
EG ( called_scope ) = current_called_scope ;
2002-03-01 14:27:26 +00:00
EG ( scope ) = current_scope ;
EG ( This ) = current_this ;
2003-08-05 10:24:40 +00:00
EG ( current_execute_data ) = EX ( prev_execute_data ) ;
2004-02-03 12:17:09 +00:00
if ( EG ( exception ) ) {
zend_throw_exception_internal ( NULL TSRMLS_CC ) ;
}
2005-08-11 23:35:03 +00:00
if ( old_func_name ) {
efree ( Z_STRVAL_P ( fci - > function_name ) ) ;
Z_TYPE_P ( fci - > function_name ) = IS_STRING ;
Z_STRVAL_P ( fci - > function_name ) = old_func_name ;
}
2003-08-05 10:24:40 +00:00
return SUCCESS ;
1999-04-07 18:10:10 +00:00
}
2007-07-11 11:19:58 +00:00
/* }}} */
1999-04-07 18:10:10 +00:00
2007-09-11 11:23:12 +00:00
ZEND_API int zend_u_lookup_class_ex ( zend_uchar type , zstr name , int name_length , zstr autoload_name , int do_normalize , zend_class_entry * * * ce TSRMLS_DC ) /* { { { */
2002-06-16 18:25:05 +00:00
{
2002-06-26 15:13:14 +00:00
zval * * args [ 1 ] ;
2003-11-07 11:47:50 +00:00
zval autoload_function ;
2005-05-26 14:28:24 +00:00
zval * class_name_ptr ;
2005-12-20 11:25:39 +00:00
zval * retval_ptr = NULL ;
2002-06-26 15:13:14 +00:00
int retval ;
2005-08-11 23:35:03 +00:00
unsigned int lc_name_len ;
2007-07-12 09:23:48 +00:00
zstr lc_name , lc_free ;
2004-03-24 14:30:59 +00:00
char dummy = 1 ;
2004-08-23 20:57:40 +00:00
zend_fcall_info fcall_info ;
zend_fcall_info_cache fcall_cache ;
2009-04-08 13:18:15 +00:00
ulong hash ;
2004-11-17 12:06:27 +00:00
2007-03-03 13:46:19 +00:00
if ( name . v = = NULL | | ! name_length ) {
2004-11-17 12:06:27 +00:00
return FAILURE ;
}
2006-02-21 08:00:39 +00:00
2006-07-18 17:52:45 +00:00
if ( do_normalize ) {
2007-07-12 09:23:48 +00:00
lc_free = lc_name = zend_u_str_case_fold ( type , name , name_length , 1 , & lc_name_len ) ;
2006-07-18 17:52:45 +00:00
} else {
lc_name = name ;
lc_name_len = name_length ;
}
2007-08-20 09:48:41 +00:00
2008-12-04 20:12:30 +00:00
/* Ignore leading "\" */
2007-07-12 09:23:48 +00:00
if ( type = = IS_UNICODE & &
2008-12-04 20:12:30 +00:00
lc_name . u [ 0 ] = = ' \\ ' ) {
lc_name . u + = 1 ;
lc_name_len - = 1 ;
2007-07-12 09:23:48 +00:00
} else if ( type = = IS_STRING & &
2008-12-04 20:12:30 +00:00
lc_name . s [ 0 ] = = ' \\ ' ) {
lc_name . s + = 1 ;
lc_name_len - = 1 ;
2007-07-12 09:23:48 +00:00
}
2003-11-24 18:13:29 +00:00
2009-04-08 13:18:15 +00:00
hash = zend_u_inline_hash_func ( type , lc_name , lc_name_len + 1 ) ;
if ( zend_u_hash_quick_find ( EG ( class_table ) , type , lc_name , lc_name_len + 1 , hash , ( void * * ) ce ) = = SUCCESS ) {
2006-07-18 17:52:45 +00:00
if ( do_normalize ) {
2007-07-12 09:23:48 +00:00
efree ( lc_free . v ) ;
2006-07-18 17:52:45 +00:00
}
2002-06-26 15:13:14 +00:00
return SUCCESS ;
}
2004-03-28 09:37:30 +00:00
/* The compiler is not-reentrant. Make sure we __autoload() only during run-time
* ( doesn ' t impact fuctionality of __autoload ( )
*/
2007-09-11 11:23:12 +00:00
if ( ! autoload_name . v | | zend_is_compiling ( TSRMLS_C ) ) {
2006-07-18 17:52:45 +00:00
if ( do_normalize ) {
2007-07-12 09:23:48 +00:00
efree ( lc_free . v ) ;
2006-07-18 17:52:45 +00:00
}
2004-03-28 09:37:30 +00:00
return FAILURE ;
}
2004-03-24 14:30:59 +00:00
if ( EG ( in_autoload ) = = NULL ) {
2004-03-25 08:14:33 +00:00
ALLOC_HASHTABLE ( EG ( in_autoload ) ) ;
2005-08-11 23:35:03 +00:00
zend_u_hash_init ( EG ( in_autoload ) , 0 , NULL , NULL , 0 , UG ( unicode ) ) ;
2004-03-24 14:30:59 +00:00
}
2006-02-21 08:00:39 +00:00
2009-04-08 13:18:15 +00:00
if ( zend_u_hash_quick_add ( EG ( in_autoload ) , type , lc_name , lc_name_len + 1 , hash , ( void * * ) & dummy , sizeof ( char ) , NULL ) = = FAILURE ) {
2006-07-18 17:52:45 +00:00
if ( do_normalize ) {
2007-07-12 09:23:48 +00:00
efree ( lc_free . v ) ;
2006-07-18 17:52:45 +00:00
}
2003-12-23 10:45:10 +00:00
return FAILURE ;
}
2007-11-02 00:15:13 +00:00
ZVAL_ASCII_STRINGL ( & autoload_function , ZEND_AUTOLOAD_FUNC_NAME , sizeof ( ZEND_AUTOLOAD_FUNC_NAME ) - 1 , 0 ) ;
2002-06-16 18:25:05 +00:00
2005-05-26 14:28:24 +00:00
ALLOC_ZVAL ( class_name_ptr ) ;
2003-11-07 11:47:50 +00:00
INIT_PZVAL ( class_name_ptr ) ;
2008-12-04 20:12:30 +00:00
ZVAL_ZSTRL ( class_name_ptr , type , autoload_name , name_length , 1 ) ;
2006-02-21 08:00:39 +00:00
2003-11-07 11:47:50 +00:00
args [ 0 ] = & class_name_ptr ;
2006-02-21 08:00:39 +00:00
2004-08-23 20:57:40 +00:00
fcall_info . size = sizeof ( fcall_info ) ;
fcall_info . function_table = EG ( function_table ) ;
fcall_info . function_name = & autoload_function ;
fcall_info . symbol_table = NULL ;
fcall_info . retval_ptr_ptr = & retval_ptr ;
fcall_info . param_count = 1 ;
fcall_info . params = args ;
2008-11-27 19:02:45 +00:00
fcall_info . object_ptr = NULL ;
2004-08-23 20:57:40 +00:00
fcall_info . no_separation = 1 ;
fcall_cache . initialized = EG ( autoload_func ) ? 1 : 0 ;
fcall_cache . function_handler = EG ( autoload_func ) ;
fcall_cache . calling_scope = NULL ;
2008-07-25 08:53:11 +00:00
fcall_cache . called_scope = NULL ;
2008-11-27 19:02:45 +00:00
fcall_cache . object_ptr = NULL ;
2002-06-26 15:13:14 +00:00
2008-08-14 10:06:39 +00:00
zend_exception_save ( TSRMLS_C ) ;
2004-08-23 20:57:40 +00:00
retval = zend_call_function ( & fcall_info , & fcall_cache TSRMLS_CC ) ;
2008-09-15 10:19:15 +00:00
zend_exception_restore ( TSRMLS_C ) ;
2004-08-23 20:57:40 +00:00
EG ( autoload_func ) = fcall_cache . function_handler ;
2003-08-07 07:37:19 +00:00
2009-03-26 20:02:53 +00:00
zval_dtor ( & autoload_function ) ;
2006-01-17 12:18:53 +00:00
2005-05-26 14:28:24 +00:00
zval_ptr_dtor ( & class_name_ptr ) ;
2009-04-08 13:18:15 +00:00
zend_u_hash_quick_del ( EG ( in_autoload ) , type , lc_name , lc_name_len + 1 , hash ) ;
2003-12-23 10:45:10 +00:00
2008-09-15 10:19:15 +00:00
if ( retval_ptr ) {
zval_ptr_dtor ( & retval_ptr ) ;
2002-06-26 15:13:14 +00:00
}
2008-09-15 10:19:15 +00:00
if ( retval = = FAILURE ) {
2006-07-18 17:52:45 +00:00
if ( do_normalize ) {
2007-07-12 09:23:48 +00:00
efree ( lc_free . v ) ;
2006-07-18 17:52:45 +00:00
}
2003-12-11 18:18:52 +00:00
return FAILURE ;
2002-08-13 16:46:40 +00:00
}
2002-06-26 15:13:14 +00:00
2009-04-08 13:18:15 +00:00
retval = zend_u_hash_quick_find ( EG ( class_table ) , type , lc_name , lc_name_len + 1 , hash , ( void * * ) ce ) ;
2006-07-18 17:52:45 +00:00
if ( do_normalize ) {
2007-07-12 09:23:48 +00:00
efree ( lc_free . v ) ;
2006-07-18 17:52:45 +00:00
}
2003-11-24 18:13:29 +00:00
return retval ;
2002-06-26 15:13:14 +00:00
}
2007-07-11 11:19:58 +00:00
/* }}} */
1999-04-07 18:10:10 +00:00
2007-07-11 11:19:58 +00:00
ZEND_API int zend_u_lookup_class ( zend_uchar type , zstr name , int name_length , zend_class_entry * * * ce TSRMLS_DC ) /* { { { */
2005-08-23 07:23:30 +00:00
{
2007-09-11 11:23:12 +00:00
return zend_u_lookup_class_ex ( type , name , name_length , name , 1 , ce TSRMLS_CC ) ;
2005-08-23 07:23:30 +00:00
}
2007-07-11 11:19:58 +00:00
/* }}} */
2005-08-23 07:23:30 +00:00
2007-09-11 11:23:12 +00:00
ZEND_API int zend_lookup_class_ex ( char * name , int name_length , char * autoload_name , zend_class_entry * * * ce TSRMLS_DC ) /* { { { */
2006-11-08 10:09:17 +00:00
{
2007-09-11 11:23:12 +00:00
return zend_u_lookup_class_ex ( IS_STRING , ZSTR ( name ) , name_length , ZSTR ( autoload_name ) , 1 , ce TSRMLS_CC ) ;
2006-11-08 10:09:17 +00:00
}
2007-07-11 11:19:58 +00:00
/* }}} */
2006-11-08 10:09:17 +00:00
2007-07-11 11:19:58 +00:00
ZEND_API int zend_lookup_class ( char * name , int name_length , zend_class_entry * * * ce TSRMLS_DC ) /* { { { */
2005-08-11 23:35:03 +00:00
{
2006-02-26 11:57:14 +00:00
return zend_u_lookup_class ( IS_STRING , ZSTR ( name ) , name_length , ce TSRMLS_CC ) ;
2005-08-11 23:35:03 +00:00
}
2007-07-11 11:19:58 +00:00
/* }}} */
2005-08-11 23:35:03 +00:00
2009-06-05 18:50:10 +00:00
ZEND_API int zend_u_eval_stringl ( zend_uchar type , zstr string , int str_len , zval * retval_ptr , char * string_name TSRMLS_DC ) /* { { { */
1999-04-07 18:10:10 +00:00
{
zval pv ;
zend_op_array * new_op_array ;
zend_op_array * original_active_op_array = EG ( active_op_array ) ;
2008-03-18 08:36:49 +00:00
zend_uint original_compiler_options ;
2000-05-06 18:49:46 +00:00
int retval ;
1999-04-07 18:10:10 +00:00
2005-08-11 23:35:03 +00:00
if ( type = = IS_UNICODE ) {
2006-02-21 20:12:43 +00:00
UChar * str = string . u ;
2005-08-11 23:35:03 +00:00
if ( retval_ptr ) {
2009-06-05 18:50:10 +00:00
Z_USTRLEN ( pv ) = str_len + sizeof ( " return ; " ) - 1 ;
2007-11-02 00:15:13 +00:00
Z_USTRVAL ( pv ) = eumalloc ( Z_USTRLEN ( pv ) + 1 ) ;
2009-03-19 18:32:45 +00:00
u_memcpy ( Z_USTRVAL ( pv ) , u_return , sizeof ( " return " ) - 1 ) ;
2009-06-05 18:50:10 +00:00
u_memcpy ( Z_USTRVAL ( pv ) + sizeof ( " return " ) - 1 , str , str_len ) ;
2009-03-19 18:32:45 +00:00
Z_USTRVAL ( pv ) [ Z_USTRLEN ( pv ) - 1 ] = 0x3B /*';'*/ ;
Z_USTRVAL ( pv ) [ Z_USTRLEN ( pv ) ] = 0 ;
2005-08-11 23:35:03 +00:00
} else {
2009-06-05 18:50:10 +00:00
Z_USTRLEN ( pv ) = str_len ;
2008-04-11 09:43:49 +00:00
Z_USTRVAL ( pv ) = str ;
2005-08-11 23:35:03 +00:00
}
1999-04-07 18:10:10 +00:00
} else {
2006-02-21 20:12:43 +00:00
char * str = string . s ;
2005-08-11 23:35:03 +00:00
if ( retval_ptr ) {
2009-06-05 18:50:10 +00:00
Z_STRLEN ( pv ) = str_len + sizeof ( " return ; " ) - 1 ;
2007-11-02 00:15:13 +00:00
Z_STRVAL ( pv ) = emalloc ( Z_STRLEN ( pv ) + 1 ) ;
2009-03-19 18:32:45 +00:00
memcpy ( Z_STRVAL ( pv ) , " return " , sizeof ( " return " ) - 1 ) ;
2009-06-05 18:50:10 +00:00
memcpy ( Z_STRVAL ( pv ) + sizeof ( " return " ) - 1 , str , str_len ) ;
2009-03-19 18:32:45 +00:00
Z_STRVAL ( pv ) [ Z_STRLEN ( pv ) - 1 ] = ' ; ' ;
Z_STRVAL ( pv ) [ Z_STRLEN ( pv ) ] = ' \0 ' ;
2005-08-11 23:35:03 +00:00
} else {
2009-06-05 18:50:10 +00:00
Z_STRLEN ( pv ) = str_len ;
2008-04-11 09:43:49 +00:00
Z_STRVAL ( pv ) = str ;
2005-08-11 23:35:03 +00:00
}
1999-04-07 18:10:10 +00:00
}
2006-02-20 19:03:43 +00:00
Z_TYPE ( pv ) = type ;
1999-04-07 18:10:10 +00:00
2006-02-20 19:03:43 +00:00
/*printf("Evaluating '%s'\n", Z_STRVAL(pv));*/
1999-04-07 18:10:10 +00:00
2008-03-18 08:36:49 +00:00
original_compiler_options = CG ( compiler_options ) ;
CG ( compiler_options ) = ZEND_COMPILE_DEFAULT_FOR_EVAL ;
2006-06-13 12:56:20 +00:00
new_op_array = zend_compile_string ( & pv , string_name TSRMLS_CC ) ;
2008-03-18 08:36:49 +00:00
CG ( compiler_options ) = original_compiler_options ;
1999-04-07 18:10:10 +00:00
if ( new_op_array ) {
1999-12-19 18:54:40 +00:00
zval * local_retval_ptr = NULL ;
zval * * original_return_value_ptr_ptr = EG ( return_value_ptr_ptr ) ;
1999-04-07 18:10:10 +00:00
zend_op * * original_opline_ptr = EG ( opline_ptr ) ;
2009-07-30 05:01:53 +00:00
int orig_interactive = CG ( interactive ) ;
2003-08-07 07:37:19 +00:00
1999-12-19 18:54:40 +00:00
EG ( return_value_ptr_ptr ) = & local_retval_ptr ;
1999-04-07 18:10:10 +00:00
EG ( active_op_array ) = new_op_array ;
EG ( no_extensions ) = 1 ;
2008-04-29 09:18:54 +00:00
if ( ! EG ( active_symbol_table ) ) {
zend_rebuild_symbol_table ( TSRMLS_C ) ;
}
2009-07-30 05:01:53 +00:00
CG ( interactive ) = 0 ;
1999-12-19 18:54:40 +00:00
2001-07-27 10:10:39 +00:00
zend_execute ( new_op_array TSRMLS_CC ) ;
1999-12-19 18:54:40 +00:00
2009-07-30 05:01:53 +00:00
CG ( interactive ) = orig_interactive ;
1999-12-19 18:54:40 +00:00
if ( local_retval_ptr ) {
if ( retval_ptr ) {
COPY_PZVAL_TO_ZVAL ( * retval_ptr , local_retval_ptr ) ;
} else {
zval_ptr_dtor ( & local_retval_ptr ) ;
}
} else {
if ( retval_ptr ) {
INIT_ZVAL ( * retval_ptr ) ;
}
}
1999-04-07 18:10:10 +00:00
EG ( no_extensions ) = 0 ;
EG ( opline_ptr ) = original_opline_ptr ;
EG ( active_op_array ) = original_active_op_array ;
2003-03-26 07:44:11 +00:00
destroy_op_array ( new_op_array TSRMLS_CC ) ;
1999-04-07 18:10:10 +00:00
efree ( new_op_array ) ;
1999-12-19 18:54:40 +00:00
EG ( return_value_ptr_ptr ) = original_return_value_ptr_ptr ;
2000-05-06 18:49:46 +00:00
retval = SUCCESS ;
1999-04-07 18:10:10 +00:00
} else {
2000-05-06 18:49:46 +00:00
retval = FAILURE ;
1999-04-07 18:10:10 +00:00
}
2008-04-11 09:43:49 +00:00
if ( retval_ptr ) {
zval_dtor ( & pv ) ;
}
2000-05-06 18:49:46 +00:00
return retval ;
1999-04-07 18:10:10 +00:00
}
2007-07-11 11:19:58 +00:00
/* }}} */
1999-04-07 18:10:10 +00:00
2009-06-05 18:50:10 +00:00
ZEND_API int zend_u_eval_string ( zend_uchar type , zstr str , zval * retval_ptr , char * string_name TSRMLS_DC ) /* { { { */
{
return zend_u_eval_stringl ( type , str , ZSTR_LEN ( type , str ) , retval_ptr , string_name TSRMLS_CC ) ;
}
/* }}} */
ZEND_API int zend_eval_stringl ( char * str , int str_len , zval * retval_ptr , char * string_name TSRMLS_DC ) /* { { { */
{
return zend_u_eval_stringl ( IS_STRING , ZSTR ( str ) , str_len , retval_ptr , string_name TSRMLS_CC ) ;
}
/* }}} */
2007-07-11 11:19:58 +00:00
ZEND_API int zend_eval_string ( char * str , zval * retval_ptr , char * string_name TSRMLS_DC ) /* { { { */
2005-08-11 23:35:03 +00:00
{
2009-06-05 18:50:10 +00:00
return zend_u_eval_stringl ( IS_STRING , ZSTR ( str ) , strlen ( str ) , retval_ptr , string_name TSRMLS_CC ) ;
2005-08-11 23:35:03 +00:00
}
2007-07-11 11:19:58 +00:00
/* }}} */
1999-04-07 18:10:10 +00:00
2009-06-05 18:50:10 +00:00
ZEND_API int zend_u_eval_stringl_ex ( zend_uchar type , zstr str , int str_len , zval * retval_ptr , char * string_name , int handle_exceptions TSRMLS_DC ) /* { { { */
2003-08-24 13:10:03 +00:00
{
int result ;
2009-06-05 18:50:10 +00:00
result = zend_u_eval_stringl ( type , str , str_len , retval_ptr , string_name TSRMLS_CC ) ;
2003-08-24 13:10:03 +00:00
if ( handle_exceptions & & EG ( exception ) ) {
2009-01-02 13:14:17 +00:00
zend_exception_error ( EG ( exception ) , E_ERROR TSRMLS_CC ) ;
2003-08-24 13:10:03 +00:00
result = FAILURE ;
}
return result ;
}
2007-07-11 11:19:58 +00:00
/* }}} */
2003-08-24 13:10:03 +00:00
2009-06-05 18:50:10 +00:00
ZEND_API int zend_u_eval_string_ex ( zend_uchar type , zstr str , zval * retval_ptr , char * string_name , int handle_exceptions TSRMLS_DC ) /* { { { */
{
return zend_u_eval_stringl_ex ( type , str , ZSTR_LEN ( type , str ) , retval_ptr , string_name , handle_exceptions TSRMLS_CC ) ;
}
/* }}} */
ZEND_API int zend_eval_stringl_ex ( char * str , int str_len , zval * retval_ptr , char * string_name , int handle_exceptions TSRMLS_DC ) /* { { { */
{
return zend_u_eval_stringl_ex ( IS_STRING , ZSTR ( str ) , str_len , retval_ptr , string_name , handle_exceptions TSRMLS_CC ) ;
}
/* }}} */
2007-07-11 11:19:58 +00:00
ZEND_API int zend_eval_string_ex ( char * str , zval * retval_ptr , char * string_name , int handle_exceptions TSRMLS_DC ) /* { { { */
2005-08-11 23:35:03 +00:00
{
2009-06-05 18:50:10 +00:00
return zend_u_eval_stringl_ex ( IS_STRING , ZSTR ( str ) , strlen ( str ) , retval_ptr , string_name , handle_exceptions TSRMLS_CC ) ;
2005-08-11 23:35:03 +00:00
}
2007-07-11 11:19:58 +00:00
/* }}} */
2005-08-11 23:35:03 +00:00
2007-07-11 11:19:58 +00:00
void execute_new_code ( TSRMLS_D ) /* { { { */
1999-04-07 18:10:10 +00:00
{
2004-03-16 14:59:06 +00:00
zend_op * opline , * end ;
2001-07-15 14:08:58 +00:00
zend_op * ret_opline ;
2009-07-30 05:01:53 +00:00
int orig_interactive ;
1999-04-07 18:10:10 +00:00
2007-02-15 10:42:52 +00:00
if ( ! ( CG ( active_op_array ) - > fn_flags & ZEND_ACC_INTERACTIVE )
1999-04-27 11:00:59 +00:00
| | CG ( active_op_array ) - > backpatch_count > 0
2006-02-21 20:12:43 +00:00
| | CG ( active_op_array ) - > function_name . v
1999-04-27 11:00:59 +00:00
| | CG ( active_op_array ) - > type ! = ZEND_USER_FUNCTION ) {
1999-04-07 18:10:10 +00:00
return ;
}
2001-04-30 04:50:34 +00:00
2001-07-28 10:51:54 +00:00
ret_opline = get_next_op ( CG ( active_op_array ) TSRMLS_CC ) ;
2001-07-15 14:08:58 +00:00
ret_opline - > opcode = ZEND_RETURN ;
ret_opline - > op1 . op_type = IS_CONST ;
INIT_ZVAL ( ret_opline - > op1 . u . constant ) ;
SET_UNUSED ( ret_opline - > op2 ) ;
if ( ! CG ( active_op_array ) - > start_op ) {
CG ( active_op_array ) - > start_op = CG ( active_op_array ) - > opcodes ;
}
2003-08-07 07:37:19 +00:00
2001-07-15 14:08:58 +00:00
opline = CG ( active_op_array ) - > start_op ;
2001-05-06 15:00:58 +00:00
end = CG ( active_op_array ) - > opcodes + CG ( active_op_array ) - > last ;
2001-04-30 04:50:34 +00:00
2004-03-16 14:59:06 +00:00
while ( opline < end ) {
2007-11-02 00:15:13 +00:00
if ( opline - > op1 . op_type = = IS_CONST ) {
2007-10-07 05:15:07 +00:00
Z_SET_ISREF ( opline - > op1 . u . constant ) ;
Z_SET_REFCOUNT ( opline - > op1 . u . constant , 2 ) ; /* Make sure is_ref won't be reset */
2004-03-16 14:59:06 +00:00
}
2007-11-02 00:15:13 +00:00
if ( opline - > op2 . op_type = = IS_CONST ) {
2007-10-07 05:15:07 +00:00
Z_SET_ISREF ( opline - > op2 . u . constant ) ;
Z_SET_REFCOUNT ( opline - > op2 . u . constant , 2 ) ;
2004-03-16 14:59:06 +00:00
}
2005-03-26 02:43:02 +00:00
switch ( opline - > opcode ) {
2006-03-10 08:29:43 +00:00
case ZEND_GOTO :
if ( Z_TYPE ( opline - > op2 . u . constant ) ! = IS_LONG ) {
zend_resolve_goto_label ( CG ( active_op_array ) , opline , 1 TSRMLS_CC ) ;
}
/* break omitted intentionally */
2005-03-26 02:43:02 +00:00
case ZEND_JMP :
opline - > op1 . u . jmp_addr = & CG ( active_op_array ) - > opcodes [ opline - > op1 . u . opline_num ] ;
break ;
case ZEND_JMPZ :
case ZEND_JMPNZ :
case ZEND_JMPZ_EX :
case ZEND_JMPNZ_EX :
2007-03-08 17:30:28 +00:00
case ZEND_JMP_SET :
2005-03-26 02:43:02 +00:00
opline - > op2 . u . jmp_addr = & CG ( active_op_array ) - > opcodes [ opline - > op2 . u . opline_num ] ;
break ;
}
2004-09-23 21:43:32 +00:00
ZEND_VM_SET_OPCODE_HANDLER ( opline ) ;
2003-06-15 11:44:30 +00:00
opline + + ;
2004-03-16 14:59:06 +00:00
}
2001-04-30 04:50:34 +00:00
2006-03-10 08:29:43 +00:00
zend_release_labels ( TSRMLS_C ) ;
2008-04-11 09:43:49 +00:00
EG ( return_value_ptr_ptr ) = NULL ;
1999-04-07 18:10:10 +00:00
EG ( active_op_array ) = CG ( active_op_array ) ;
2009-07-30 05:01:53 +00:00
orig_interactive = CG ( interactive ) ;
CG ( interactive ) = 0 ;
2001-07-27 10:10:39 +00:00
zend_execute ( CG ( active_op_array ) TSRMLS_CC ) ;
2009-07-30 05:01:53 +00:00
CG ( interactive ) = orig_interactive ;
2006-02-21 08:00:39 +00:00
2005-11-24 11:32:44 +00:00
if ( EG ( exception ) ) {
2009-01-02 13:14:17 +00:00
zend_exception_error ( EG ( exception ) , E_ERROR TSRMLS_CC ) ;
2005-11-24 11:32:44 +00:00
}
2001-09-10 00:07:32 +00:00
2008-01-21 19:41:41 +00:00
CG ( active_op_array ) - > last - = 1 ; /* get rid of that ZEND_RETURN */
2001-07-15 14:08:58 +00:00
CG ( active_op_array ) - > start_op = CG ( active_op_array ) - > opcodes + CG ( active_op_array ) - > last ;
1999-04-07 18:10:10 +00:00
}
2007-07-11 11:19:58 +00:00
/* }}} */
1999-04-12 18:29:09 +00:00
2007-07-11 11:19:58 +00:00
ZEND_API void zend_timeout ( int dummy ) /* { { { */
2000-06-16 01:54:56 +00:00
{
2001-07-27 10:10:39 +00:00
TSRMLS_FETCH ( ) ;
2000-06-16 01:54:56 +00:00
2002-09-19 15:58:01 +00:00
if ( zend_on_timeout ) {
zend_on_timeout ( EG ( timeout_seconds ) TSRMLS_CC ) ;
}
2003-01-23 05:15:42 +00:00
2007-11-02 00:15:13 +00:00
zend_error ( E_ERROR , " Maximum execution time of %d second%s exceeded " , EG ( timeout_seconds ) , EG ( timeout_seconds ) = = 1 ? " " : " s " ) ;
2000-06-16 01:54:56 +00:00
}
2007-07-11 11:19:58 +00:00
/* }}} */
2000-06-16 01:54:56 +00:00
2000-06-16 02:49:21 +00:00
# ifdef ZEND_WIN32
2007-07-11 11:19:58 +00:00
static LRESULT CALLBACK zend_timeout_WndProc ( HWND hWnd , UINT message , WPARAM wParam , LPARAM lParam ) /* { { { */
2000-06-16 01:54:56 +00:00
{
switch ( message ) {
case WM_DESTROY :
PostQuitMessage ( 0 ) ;
2000-06-16 14:27:28 +00:00
break ;
case WM_REGISTER_ZEND_TIMEOUT :
/* wParam is the thread id pointer, lParam is the timeout amount in seconds */
2007-11-02 00:15:13 +00:00
if ( lParam = = 0 ) {
2000-06-26 15:17:36 +00:00
KillTimer ( timeout_window , wParam ) ;
} else {
2004-05-18 20:14:54 +00:00
# ifdef ZTS
2004-01-28 09:07:02 +00:00
void * * * tsrm_ls ;
2004-05-18 20:14:54 +00:00
# endif
2000-06-26 15:17:36 +00:00
SetTimer ( timeout_window , wParam , lParam * 1000 , NULL ) ;
2004-05-18 20:14:54 +00:00
# ifdef ZTS
2004-01-28 09:07:02 +00:00
tsrm_ls = ts_resource_ex ( 0 , & wParam ) ;
if ( ! tsrm_ls ) {
/* shouldn't normally happen */
break ;
}
2004-05-18 20:14:54 +00:00
# endif
2004-01-28 09:07:02 +00:00
EG ( timed_out ) = 0 ;
2000-06-26 15:17:36 +00:00
}
2000-06-16 14:27:28 +00:00
break ;
case WM_UNREGISTER_ZEND_TIMEOUT :
/* wParam is the thread id pointer */
KillTimer ( timeout_window , wParam ) ;
break ;
case WM_TIMER : {
# ifdef ZTS
2001-07-28 10:51:54 +00:00
void * * * tsrm_ls ;
2000-06-16 14:27:28 +00:00
2001-07-28 10:51:54 +00:00
tsrm_ls = ts_resource_ex ( 0 , & wParam ) ;
if ( ! tsrm_ls ) {
2000-06-16 14:27:28 +00:00
/* Thread died before receiving its timeout? */
break ;
}
# endif
KillTimer ( timeout_window , wParam ) ;
2001-07-28 10:51:54 +00:00
EG ( timed_out ) = 1 ;
2000-06-16 14:27:28 +00:00
}
break ;
2000-06-16 01:54:56 +00:00
default :
2001-08-11 15:56:40 +00:00
return DefWindowProc ( hWnd , message , wParam , lParam ) ;
2000-06-16 01:54:56 +00:00
}
2000-06-16 14:27:28 +00:00
return 0 ;
2000-06-16 01:54:56 +00:00
}
2007-07-11 11:19:58 +00:00
/* }}} */
2000-06-16 01:54:56 +00:00
2007-07-11 11:19:58 +00:00
static unsigned __stdcall timeout_thread_proc ( void * pArgs ) /* { { { */
2000-06-16 01:54:56 +00:00
{
2000-06-16 14:27:28 +00:00
MSG message ;
2000-06-16 01:54:56 +00:00
wc . style = 0 ;
wc . lpfnWndProc = zend_timeout_WndProc ;
wc . cbClsExtra = 0 ;
wc . cbWndExtra = 0 ;
wc . hInstance = NULL ;
wc . hIcon = NULL ;
wc . hCursor = NULL ;
wc . hbrBackground = ( HBRUSH ) ( COLOR_BACKGROUND + 5 ) ;
wc . lpszMenuName = NULL ;
wc . lpszClassName = " Zend Timeout Window " ;
2001-04-27 18:51:56 +00:00
if ( ! RegisterClass ( & wc ) ) {
2000-06-16 14:27:28 +00:00
return - 1 ;
}
timeout_window = CreateWindow ( wc . lpszClassName , wc . lpszClassName , 0 , CW_USEDEFAULT , CW_USEDEFAULT , CW_USEDEFAULT , CW_USEDEFAULT , NULL , NULL , NULL , NULL ) ;
SetEvent ( timeout_thread_event ) ;
while ( GetMessage ( & message , NULL , 0 , 0 ) ) {
SendMessage ( timeout_window , message . message , message . wParam , message . lParam ) ;
if ( message . message = = WM_QUIT ) {
break ;
}
2000-06-16 01:54:56 +00:00
}
2000-06-16 14:27:28 +00:00
DestroyWindow ( timeout_window ) ;
UnregisterClass ( wc . lpszClassName , NULL ) ;
2005-12-22 16:46:03 +00:00
SetEvent ( timeout_thread_handle ) ;
2000-06-16 14:27:28 +00:00
return 0 ;
2000-06-16 01:54:56 +00:00
}
2007-07-11 11:19:58 +00:00
/* }}} */
2000-06-16 01:54:56 +00:00
2007-07-21 00:34:41 +00:00
void zend_init_timeout_thread ( void ) /* { { { */
2000-06-16 01:54:56 +00:00
{
2000-06-16 14:27:28 +00:00
timeout_thread_event = CreateEvent ( NULL , FALSE , FALSE , NULL ) ;
2005-12-22 16:46:03 +00:00
timeout_thread_handle = CreateEvent ( NULL , FALSE , FALSE , NULL ) ;
_beginthreadex ( NULL , 0 , timeout_thread_proc , NULL , 0 , & timeout_thread_id ) ;
2000-06-16 14:27:28 +00:00
WaitForSingleObject ( timeout_thread_event , INFINITE ) ;
2000-06-16 01:54:56 +00:00
}
2007-07-11 11:19:58 +00:00
/* }}} */
2000-06-16 01:54:56 +00:00
2007-07-21 00:34:41 +00:00
void zend_shutdown_timeout_thread ( void ) /* { { { */
2000-06-16 01:54:56 +00:00
{
2000-06-16 14:27:28 +00:00
if ( ! timeout_thread_initialized ) {
return ;
}
PostThreadMessage ( timeout_thread_id , WM_QUIT , 0 , 0 ) ;
2005-12-09 18:09:08 +00:00
/* Wait for thread termination */
WaitForSingleObject ( timeout_thread_handle , 5000 ) ;
CloseHandle ( timeout_thread_handle ) ;
2006-05-25 07:23:38 +00:00
timeout_thread_initialized = 0 ;
2000-06-16 01:54:56 +00:00
}
2007-07-11 11:19:58 +00:00
/* }}} */
2000-06-16 14:27:28 +00:00
2000-06-16 01:54:56 +00:00
# endif
/* This one doesn't exists on QNX */
# ifndef SIGPROF
# define SIGPROF 27
# endif
2008-03-19 16:37:49 +00:00
void zend_set_timeout ( long seconds , int reset_signals ) /* { { { */
2000-06-16 01:54:56 +00:00
{
2001-07-27 10:10:39 +00:00
TSRMLS_FETCH ( ) ;
2000-06-16 01:54:56 +00:00
EG ( timeout_seconds ) = seconds ;
2008-03-19 16:37:49 +00:00
# ifdef ZEND_WIN32
2006-11-10 11:51:55 +00:00
if ( ! seconds ) {
return ;
}
2007-11-02 00:15:13 +00:00
if ( timeout_thread_initialized = = 0 & & InterlockedIncrement ( & timeout_thread_initialized ) = = 1 ) {
2000-06-16 14:27:28 +00:00
/* We start up this process-wide thread here and not in zend_startup(), because if Zend
* is initialized inside a DllMain ( ) , you ' re not supposed to start threads from it .
*/
zend_init_timeout_thread ( ) ;
}
PostThreadMessage ( timeout_thread_id , WM_REGISTER_ZEND_TIMEOUT , ( WPARAM ) GetCurrentThreadId ( ) , ( LPARAM ) seconds ) ;
2000-06-16 01:54:56 +00:00
# else
# ifdef HAVE_SETITIMER
2000-06-16 02:49:21 +00:00
{
struct itimerval t_r ; /* timeout requested */
2000-07-03 16:53:39 +00:00
sigset_t sigset ;
2008-03-19 16:37:49 +00:00
if ( seconds ) {
t_r . it_value . tv_sec = seconds ;
t_r . it_value . tv_usec = t_r . it_interval . tv_sec = t_r . it_interval . tv_usec = 0 ;
2000-06-16 01:54:56 +00:00
2005-07-12 06:52:59 +00:00
# ifdef __CYGWIN__
2008-03-19 16:37:49 +00:00
setitimer ( ITIMER_REAL , & t_r , NULL ) ;
}
if ( reset_signals ) {
signal ( SIGALRM , zend_timeout ) ;
sigemptyset ( & sigset ) ;
sigaddset ( & sigset , SIGALRM ) ;
}
2005-07-12 06:52:59 +00:00
# else
2008-03-19 16:37:49 +00:00
setitimer ( ITIMER_PROF , & t_r , NULL ) ;
}
if ( reset_signals ) {
signal ( SIGPROF , zend_timeout ) ;
sigemptyset ( & sigset ) ;
sigaddset ( & sigset , SIGPROF ) ;
}
2005-07-12 06:52:59 +00:00
# endif
2008-03-19 16:37:49 +00:00
if ( reset_signals ) {
sigprocmask ( SIG_UNBLOCK , & sigset , NULL ) ;
}
2000-06-16 02:49:21 +00:00
}
2000-06-16 01:54:56 +00:00
# endif
# endif
}
2007-07-11 11:19:58 +00:00
/* }}} */
2000-06-16 01:54:56 +00:00
2007-07-11 11:19:58 +00:00
void zend_unset_timeout ( TSRMLS_D ) /* { { { */
2000-06-16 01:54:56 +00:00
{
# ifdef ZEND_WIN32
2006-11-10 11:51:55 +00:00
if ( timeout_thread_initialized ) {
PostThreadMessage ( timeout_thread_id , WM_UNREGISTER_ZEND_TIMEOUT , ( WPARAM ) GetCurrentThreadId ( ) , ( LPARAM ) 0 ) ;
}
2000-06-16 01:54:56 +00:00
# else
# ifdef HAVE_SETITIMER
2000-06-16 02:49:21 +00:00
{
struct itimerval no_timeout ;
2000-06-16 01:54:56 +00:00
2000-06-16 02:49:21 +00:00
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 ;
2000-06-16 01:54:56 +00:00
2005-08-02 17:01:17 +00:00
# ifdef __CYGWIN__
setitimer ( ITIMER_REAL , & no_timeout , NULL ) ;
# else
2000-06-16 02:49:21 +00:00
setitimer ( ITIMER_PROF , & no_timeout , NULL ) ;
2005-08-02 17:01:17 +00:00
# endif
2000-06-16 02:49:21 +00:00
}
2000-06-16 01:54:56 +00:00
# endif
# endif
}
2007-07-11 11:19:58 +00:00
/* }}} */
2003-02-01 01:49:15 +00:00
2007-07-11 11:19:58 +00:00
ZEND_API zend_class_entry * zend_u_fetch_class ( zend_uchar type , zstr class_name , uint class_name_len , int fetch_type TSRMLS_DC ) /* { { { */
2003-08-03 08:21:08 +00:00
{
zend_class_entry * * pce ;
2006-07-18 17:52:45 +00:00
int use_autoload = ( fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD ) ? 0 : 1 ;
2007-10-03 10:33:45 +00:00
int silent = ( fetch_type & ZEND_FETCH_CLASS_SILENT ) ! = 0 ;
2006-07-18 17:52:45 +00:00
zstr lcname = class_name ;
2007-10-03 10:33:45 +00:00
fetch_type & = ZEND_FETCH_CLASS_MASK ;
2003-08-03 08:21:08 +00:00
check_fetch_type :
switch ( fetch_type ) {
case ZEND_FETCH_CLASS_SELF :
if ( ! EG ( scope ) ) {
zend_error ( E_ERROR , " Cannot access self:: when no class scope is active " ) ;
}
return EG ( scope ) ;
case ZEND_FETCH_CLASS_PARENT :
if ( ! EG ( scope ) ) {
zend_error ( E_ERROR , " Cannot access parent:: when no class scope is active " ) ;
}
if ( ! EG ( scope ) - > parent ) {
zend_error ( E_ERROR , " Cannot access parent:: when current class scope has no parent " ) ;
}
return EG ( scope ) - > parent ;
2007-09-26 07:16:33 +00:00
case ZEND_FETCH_CLASS_STATIC :
if ( ! EG ( called_scope ) ) {
zend_error ( E_ERROR , " Cannot access static:: when no class scope is active " ) ;
}
return EG ( called_scope ) ;
2003-08-03 08:21:08 +00:00
case ZEND_FETCH_CLASS_AUTO : {
2006-07-18 17:52:45 +00:00
fetch_type = zend_get_class_fetch_type ( type , lcname , class_name_len ) ;
2003-08-03 08:21:08 +00:00
if ( fetch_type ! = ZEND_FETCH_CLASS_DEFAULT ) {
2007-09-11 11:23:12 +00:00
if ( lcname . v ! = class_name . v ) {
2006-07-18 17:52:45 +00:00
efree ( lcname . v ) ;
}
2003-08-03 08:21:08 +00:00
goto check_fetch_type ;
}
}
break ;
}
2008-12-04 20:12:30 +00:00
if ( zend_u_lookup_class_ex ( type , lcname , class_name_len , ( use_autoload ? class_name : NULL_ZSTR ) , 1 , & pce TSRMLS_CC ) = = FAILURE ) {
2007-08-22 07:39:37 +00:00
if ( use_autoload ) {
2008-09-15 10:19:15 +00:00
if ( ! silent & & ! EG ( exception ) ) {
2007-10-03 10:33:45 +00:00
if ( fetch_type = = ZEND_FETCH_CLASS_INTERFACE ) {
zend_error ( E_ERROR , " Interface '%R' not found " , type , class_name ) ;
} else {
zend_error ( E_ERROR , " Class '%R' not found " , type , class_name ) ;
}
2005-08-19 08:11:16 +00:00
}
}
2005-08-23 07:23:30 +00:00
return NULL ;
2003-08-03 08:21:08 +00:00
}
2008-12-04 20:12:30 +00:00
return * pce ;
2003-08-03 08:21:08 +00:00
}
2007-07-11 11:19:58 +00:00
/* }}} */
2003-08-03 08:21:08 +00:00
2007-07-11 11:19:58 +00:00
zend_class_entry * zend_fetch_class ( char * class_name , uint class_name_len , int fetch_type TSRMLS_DC ) /* { { { */
2005-08-11 23:35:03 +00:00
{
2006-02-26 11:57:14 +00:00
return zend_u_fetch_class ( IS_STRING , ZSTR ( class_name ) , class_name_len , fetch_type TSRMLS_CC ) ;
2005-08-11 23:35:03 +00:00
}
2007-07-11 11:19:58 +00:00
/* }}} */
2004-02-03 12:17:09 +00:00
2004-02-04 16:30:15 +00:00
# define MAX_ABSTRACT_INFO_CNT 3
2005-08-11 23:35:03 +00:00
# define MAX_ABSTRACT_INFO_FMT "%v%s%v%s"
2004-02-04 16:30:15 +00:00
# define DISPLAY_ABSTRACT_FN(idx) \
2006-02-26 11:57:14 +00:00
ai . afn [ idx ] ? ZEND_FN_SCOPE_NAME ( ai . afn [ idx ] ) : EMPTY_ZSTR , \
2004-02-04 16:30:15 +00:00
ai . afn [ idx ] ? " :: " : " " , \
2006-02-26 11:57:14 +00:00
ai . afn [ idx ] ? ai . afn [ idx ] - > common . function_name : EMPTY_ZSTR , \
2007-11-02 00:15:13 +00:00
ai . afn [ idx ] & & ai . afn [ idx + 1 ] ? " , " : ( ai . afn [ idx ] & & ai . cnt > MAX_ABSTRACT_INFO_CNT ? " , ... " : " " )
2004-02-04 16:30:15 +00:00
typedef struct _zend_abstract_info {
2007-11-02 00:15:13 +00:00
zend_function * afn [ MAX_ABSTRACT_INFO_CNT + 1 ] ;
2004-02-04 16:30:15 +00:00
int cnt ;
2008-01-29 11:13:52 +00:00
int ctor ;
2004-02-04 16:30:15 +00:00
} zend_abstract_info ;
2007-07-11 11:19:58 +00:00
static int zend_verify_abstract_class_function ( zend_function * fn , zend_abstract_info * ai TSRMLS_DC ) /* { { { */
2004-02-04 16:30:15 +00:00
{
if ( fn - > common . fn_flags & ZEND_ACC_ABSTRACT ) {
if ( ai - > cnt < MAX_ABSTRACT_INFO_CNT ) {
ai - > afn [ ai - > cnt ] = fn ;
}
2008-01-29 11:13:52 +00:00
if ( fn - > common . fn_flags & ZEND_ACC_CTOR ) {
if ( ! ai - > ctor ) {
ai - > cnt + + ;
ai - > ctor = 1 ;
} else {
ai - > afn [ ai - > cnt ] = NULL ;
}
} else {
ai - > cnt + + ;
}
2004-02-04 16:30:15 +00:00
}
return 0 ;
}
2007-07-11 11:19:58 +00:00
/* }}} */
2004-02-04 16:30:15 +00:00
2007-07-11 11:19:58 +00:00
void zend_verify_abstract_class ( zend_class_entry * ce TSRMLS_DC ) /* { { { */
2004-02-04 16:30:15 +00:00
{
zend_abstract_info ai ;
2004-03-09 16:38:37 +00:00
if ( ( ce - > ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS ) & & ! ( ce - > ce_flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS ) ) {
2004-02-04 16:30:15 +00:00
memset ( & ai , 0 , sizeof ( ai ) ) ;
zend_hash_apply_with_argument ( & ce - > function_table , ( apply_func_arg_t ) zend_verify_abstract_class_function , & ai TSRMLS_CC ) ;
2004-03-08 16:52:59 +00:00
2006-02-21 08:00:39 +00:00
if ( ai . cnt ) {
zend_error ( E_ERROR , " Class %v 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 " ) " ,
ce - > name , ai . cnt ,
2005-05-02 15:55:05 +00:00
ai . cnt > 1 ? " s " : " " ,
2004-03-08 16:52:59 +00:00
DISPLAY_ABSTRACT_FN ( 0 ) ,
DISPLAY_ABSTRACT_FN ( 1 ) ,
DISPLAY_ABSTRACT_FN ( 2 )
) ;
}
2004-02-04 16:30:15 +00:00
}
}
2007-07-11 11:19:58 +00:00
/* }}} */
2004-02-04 16:30:15 +00:00
2007-07-11 11:19:58 +00:00
ZEND_API void zend_reset_all_cv ( HashTable * symbol_table TSRMLS_DC ) /* { { { */
2005-07-04 10:01:10 +00:00
{
zend_execute_data * ex ;
int i ;
2007-02-16 19:36:45 +00:00
memset ( CG ( auto_globals_cache ) , 0 , sizeof ( zval * * ) * zend_hash_num_elements ( CG ( auto_globals ) ) ) ;
2005-07-04 10:01:10 +00:00
for ( ex = EG ( current_execute_data ) ; ex ; ex = ex - > prev_execute_data ) {
2005-10-27 19:25:07 +00:00
if ( ex - > op_array & & ex - > symbol_table = = symbol_table ) {
2005-07-04 10:01:10 +00:00
for ( i = 0 ; i < ex - > op_array - > last_var ; i + + ) {
ex - > CVs [ i ] = NULL ;
}
}
}
}
2007-07-11 11:19:58 +00:00
/* }}} */
2005-07-04 10:01:10 +00:00
2007-07-11 11:19:58 +00:00
ZEND_API int zend_u_delete_global_variable ( zend_uchar type , zstr name , int name_len TSRMLS_DC ) /* { { { */
2004-10-04 19:54:35 +00:00
{
zend_execute_data * ex ;
2007-11-02 00:15:13 +00:00
ulong hash_value = zend_u_inline_hash_func ( type , name , name_len + 1 ) ;
2007-02-16 19:36:45 +00:00
zend_auto_global * auto_global ;
2004-10-04 19:54:35 +00:00
2007-11-02 00:15:13 +00:00
if ( zend_u_hash_quick_find ( CG ( auto_globals ) , type , name , name_len + 1 , hash_value , ( void * * ) & auto_global ) = = SUCCESS ) {
2007-02-16 19:36:45 +00:00
CG ( auto_globals_cache ) [ auto_global - > index ] = NULL ;
}
2007-11-02 00:15:13 +00:00
if ( zend_u_hash_quick_exists ( & EG ( symbol_table ) , type , name , name_len + 1 , hash_value ) ) {
2004-10-04 19:54:35 +00:00
for ( ex = EG ( current_execute_data ) ; ex ; ex = ex - > prev_execute_data ) {
2005-10-27 19:25:07 +00:00
if ( ex - > op_array & & ex - > symbol_table = = & EG ( symbol_table ) ) {
2004-10-04 19:54:35 +00:00
int i ;
for ( i = 0 ; i < ex - > op_array - > last_var ; i + + ) {
2004-10-05 06:53:39 +00:00
if ( ex - > op_array - > vars [ i ] . hash_value = = hash_value & &
2007-11-02 00:15:13 +00:00
ex - > op_array - > vars [ i ] . name_len = = name_len & &
2008-03-07 00:51:02 +00:00
! memcmp ( ex - > op_array - > vars [ i ] . name . v , name . v , USTR_BYTES ( type , name_len ) )
2007-11-02 00:15:13 +00:00
) {
2004-10-04 19:54:35 +00:00
ex - > CVs [ i ] = NULL ;
break ;
}
}
}
}
2008-04-29 08:15:49 +00:00
return zend_u_hash_quick_del ( & EG ( symbol_table ) , type , name , name_len + 1 , hash_value ) ;
2004-10-04 19:54:35 +00:00
}
return FAILURE ;
}
2007-07-11 11:19:58 +00:00
/* }}} */
2004-02-04 16:30:15 +00:00
2007-07-11 11:19:58 +00:00
ZEND_API int zend_delete_global_variable ( char * name , int name_len TSRMLS_DC ) /* { { { */
2005-08-11 23:35:03 +00:00
{
2006-02-26 11:57:14 +00:00
return zend_u_delete_global_variable ( IS_STRING , ZSTR ( name ) , name_len TSRMLS_CC ) ;
2005-08-11 23:35:03 +00:00
}
2007-07-11 11:19:58 +00:00
/* }}} */
2005-08-11 23:35:03 +00:00
2008-04-29 08:15:49 +00:00
ZEND_API void zend_rebuild_symbol_table ( TSRMLS_D ) /* { { { */
{
2009-03-26 20:02:53 +00:00
zend_uchar type = IS_UNICODE ;
2008-04-29 08:15:49 +00:00
zend_uint i ;
2008-09-17 15:11:40 +00:00
zend_execute_data * ex ;
2008-04-29 08:15:49 +00:00
if ( ! EG ( active_symbol_table ) ) {
2008-09-17 15:11:40 +00:00
/* Search for last called user function */
ex = EG ( current_execute_data ) ;
while ( ex & & ! ex - > op_array ) {
ex = ex - > prev_execute_data ;
}
if ( ex & & ex - > symbol_table ) {
EG ( active_symbol_table ) = ex - > symbol_table ;
return ;
}
if ( ex & & ex - > op_array ) {
2009-02-09 09:20:46 +00:00
if ( EG ( symtable_cache_ptr ) > = EG ( symtable_cache ) ) {
/*printf("Cache hit! Reusing %x\n", symtable_cache[symtable_cache_ptr]);*/
EG ( active_symbol_table ) = * ( EG ( symtable_cache_ptr ) - - ) ;
} else {
ALLOC_HASHTABLE ( EG ( active_symbol_table ) ) ;
zend_hash_init ( EG ( active_symbol_table ) , 0 , NULL , ZVAL_PTR_DTOR , 0 ) ;
/*printf("Cache miss! Initialized %x\n", EG(active_symbol_table));*/
}
2008-09-17 15:11:40 +00:00
ex - > symbol_table = EG ( active_symbol_table ) ;
2008-05-07 12:04:58 +00:00
2008-09-17 15:11:40 +00:00
if ( ex - > op_array - > this_var ! = - 1 & &
! ex - > CVs [ ex - > op_array - > this_var ] & &
2008-05-07 12:04:58 +00:00
EG ( This ) ) {
2008-09-17 15:11:40 +00:00
ex - > CVs [ ex - > op_array - > this_var ] = ( zval * * ) ex - > CVs + ex - > op_array - > last_var + ex - > op_array - > this_var ;
* ex - > CVs [ ex - > op_array - > this_var ] = EG ( This ) ;
2008-05-07 12:04:58 +00:00
}
2009-06-15 14:06:30 +00:00
for ( i = 0 ; i < ( zend_uint ) ex - > op_array - > last_var ; i + + ) {
2008-09-17 15:11:40 +00:00
if ( ex - > CVs [ i ] ) {
2008-04-29 08:15:49 +00:00
zend_u_hash_quick_update ( EG ( active_symbol_table ) ,
type ,
2008-09-17 15:11:40 +00:00
ex - > op_array - > vars [ i ] . name ,
ex - > op_array - > vars [ i ] . name_len + 1 ,
ex - > op_array - > vars [ i ] . hash_value ,
( void * * ) ex - > CVs [ i ] ,
2008-04-29 08:15:49 +00:00
sizeof ( zval * ) ,
2008-09-17 15:11:40 +00:00
( void * * ) & ex - > CVs [ i ] ) ;
2008-04-29 08:15:49 +00:00
}
}
}
}
}
/* }}} */
2003-02-01 01:49:15 +00:00
/*
* Local variables :
* tab - width : 4
* c - basic - offset : 4
* indent - tabs - mode : t
* End :
*/